1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/tiled_layer_impl.h"
7 #include "base/basictypes.h"
8 #include "base/stringprintf.h"
9 #include "cc/append_quads_data.h"
10 #include "cc/checkerboard_draw_quad.h"
11 #include "cc/debug_border_draw_quad.h"
12 #include "cc/debug_colors.h"
13 #include "cc/layer_tiling_data.h"
14 #include "cc/math_util.h"
15 #include "cc/quad_sink.h"
16 #include "cc/solid_color_draw_quad.h"
17 #include "cc/tile_draw_quad.h"
18 #include "third_party/khronos/GLES2/gl2.h"
19 #include "third_party/skia/include/core/SkColor.h"
20 #include "ui/gfx/quad_f.h"
26 class DrawableTile
: public LayerTilingData::Tile
{
28 static scoped_ptr
<DrawableTile
> create() { return make_scoped_ptr(new DrawableTile()); }
30 ResourceProvider::ResourceId
resourceId() const { return m_resourceId
; }
31 void setResourceId(ResourceProvider::ResourceId resourceId
) { m_resourceId
= resourceId
; }
32 bool contentsSwizzled() { return m_contentsSwizzled
; }
33 void setContentsSwizzled(bool contentsSwizzled
) { m_contentsSwizzled
= contentsSwizzled
; }
38 , m_contentsSwizzled(false) { }
40 ResourceProvider::ResourceId m_resourceId
;
41 bool m_contentsSwizzled
;
43 DISALLOW_COPY_AND_ASSIGN(DrawableTile
);
46 TiledLayerImpl::TiledLayerImpl(int id
)
52 TiledLayerImpl::~TiledLayerImpl()
56 ResourceProvider::ResourceId
TiledLayerImpl::contentsResourceId() const
58 // This function is only valid for single texture layers, e.g. masks.
60 DCHECK(m_tiler
->numTilesX() == 1);
61 DCHECK(m_tiler
->numTilesY() == 1);
63 DrawableTile
* tile
= tileAt(0, 0);
64 ResourceProvider::ResourceId resourceId
= tile
? tile
->resourceId() : 0;
68 void TiledLayerImpl::dumpLayerProperties(std::string
* str
, int indent
) const
70 str
->append(indentString(indent
));
71 base::StringAppendF(str
, "skipsDraw: %d\n", (!m_tiler
|| m_skipsDraw
));
72 LayerImpl::dumpLayerProperties(str
, indent
);
75 bool TiledLayerImpl::hasTileAt(int i
, int j
) const
77 return m_tiler
->tileAt(i
, j
);
80 bool TiledLayerImpl::hasResourceIdForTileAt(int i
, int j
) const
82 return hasTileAt(i
, j
) && tileAt(i
, j
)->resourceId();
85 DrawableTile
* TiledLayerImpl::tileAt(int i
, int j
) const
87 return static_cast<DrawableTile
*>(m_tiler
->tileAt(i
, j
));
90 DrawableTile
* TiledLayerImpl::createTile(int i
, int j
)
92 scoped_ptr
<DrawableTile
> tile(DrawableTile::create());
93 DrawableTile
* addedTile
= tile
.get();
94 m_tiler
->addTile(tile
.PassAs
<LayerTilingData::Tile
>(), i
, j
);
98 void TiledLayerImpl::getDebugBorderProperties(SkColor
* color
, float* width
) const
100 *color
= DebugColors::TiledContentLayerBorderColor();
101 *width
= DebugColors::TiledContentLayerBorderWidth(layerTreeHostImpl());
104 void TiledLayerImpl::appendQuads(QuadSink
& quadSink
, AppendQuadsData
& appendQuadsData
)
106 const gfx::Rect
& contentRect
= visibleContentRect();
108 if (!m_tiler
|| m_tiler
->hasEmptyBounds() || contentRect
.IsEmpty())
111 SharedQuadState
* sharedQuadState
= quadSink
.useSharedQuadState(createSharedQuadState());
112 appendDebugBorderQuad(quadSink
, sharedQuadState
, appendQuadsData
);
114 int left
, top
, right
, bottom
;
115 m_tiler
->contentRectToTileIndices(contentRect
, left
, top
, right
, bottom
);
117 if (showDebugBorders()) {
118 for (int j
= top
; j
<= bottom
; ++j
) {
119 for (int i
= left
; i
<= right
; ++i
) {
120 DrawableTile
* tile
= tileAt(i
, j
);
121 gfx::Rect tileRect
= m_tiler
->tileBounds(i
, j
);
125 if (m_skipsDraw
|| !tile
|| !tile
->resourceId()) {
126 borderColor
= DebugColors::MissingTileBorderColor();
127 borderWidth
= DebugColors::MissingTileBorderWidth(layerTreeHostImpl());
129 borderColor
= DebugColors::TileBorderColor();
130 borderWidth
= DebugColors::TileBorderWidth(layerTreeHostImpl());
132 scoped_ptr
<DebugBorderDrawQuad
> debugBorderQuad
= DebugBorderDrawQuad::Create();
133 debugBorderQuad
->SetNew(sharedQuadState
, tileRect
, borderColor
, borderWidth
);
134 quadSink
.append(debugBorderQuad
.PassAs
<DrawQuad
>(), appendQuadsData
);
142 for (int j
= top
; j
<= bottom
; ++j
) {
143 for (int i
= left
; i
<= right
; ++i
) {
144 DrawableTile
* tile
= tileAt(i
, j
);
145 gfx::Rect tileRect
= m_tiler
->tileBounds(i
, j
);
146 gfx::Rect displayRect
= tileRect
;
147 tileRect
.Intersect(contentRect
);
150 if (tileRect
.IsEmpty())
153 if (!tile
|| !tile
->resourceId()) {
154 if (drawCheckerboardForMissingTiles()) {
155 SkColor checkerColor
;
156 if (showDebugBorders())
157 checkerColor
= tile
? DebugColors::InvalidatedTileCheckerboardColor() : DebugColors::EvictedTileCheckerboardColor();
159 checkerColor
= DebugColors::DefaultCheckerboardColor();
161 scoped_ptr
<CheckerboardDrawQuad
> checkerboardQuad
= CheckerboardDrawQuad::Create();
162 checkerboardQuad
->SetNew(sharedQuadState
, tileRect
, checkerColor
);
163 appendQuadsData
.hadMissingTiles
|= quadSink
.append(checkerboardQuad
.PassAs
<DrawQuad
>(), appendQuadsData
);
165 scoped_ptr
<SolidColorDrawQuad
> solidColorQuad
= SolidColorDrawQuad::Create();
166 solidColorQuad
->SetNew(sharedQuadState
, tileRect
, backgroundColor());
167 appendQuadsData
.hadMissingTiles
|= quadSink
.append(solidColorQuad
.PassAs
<DrawQuad
>(), appendQuadsData
);
172 gfx::Rect tileOpaqueRect
= contentsOpaque() ? tileRect
: gfx::IntersectRects(tile
->opaqueRect(), contentRect
);
174 // Keep track of how the top left has moved, so the texture can be
175 // offset the same amount.
176 gfx::Vector2d displayOffset
= tileRect
.origin() - displayRect
.origin();
177 gfx::Vector2d textureOffset
= m_tiler
->textureOffset(i
, j
) + displayOffset
;
178 gfx::RectF texCoordRect
= gfx::RectF(tileRect
.size()) + textureOffset
;
180 float tileWidth
= static_cast<float>(m_tiler
->tileSize().width());
181 float tileHeight
= static_cast<float>(m_tiler
->tileSize().height());
182 gfx::Size
textureSize(tileWidth
, tileHeight
);
184 bool clipped
= false;
185 gfx::QuadF visibleContentInTargetQuad
= MathUtil::mapQuad(drawTransform(), gfx::QuadF(visibleContentRect()), clipped
);
186 bool isAxisAlignedInTarget
= !clipped
&& visibleContentInTargetQuad
.IsRectilinear();
187 bool useAA
= m_tiler
->hasBorderTexels() && !isAxisAlignedInTarget
;
189 bool leftEdgeAA
= !i
&& useAA
;
190 bool topEdgeAA
= !j
&& useAA
;
191 bool rightEdgeAA
= i
== m_tiler
->numTilesX() - 1 && useAA
;
192 bool bottomEdgeAA
= j
== m_tiler
->numTilesY() - 1 && useAA
;
194 scoped_ptr
<TileDrawQuad
> quad
= TileDrawQuad::Create();
195 quad
->SetNew(sharedQuadState
, tileRect
, tileOpaqueRect
, tile
->resourceId(), texCoordRect
, textureSize
, tile
->contentsSwizzled(), leftEdgeAA
, topEdgeAA
, rightEdgeAA
, bottomEdgeAA
);
196 quadSink
.append(quad
.PassAs
<DrawQuad
>(), appendQuadsData
);
201 void TiledLayerImpl::setTilingData(const LayerTilingData
& tiler
)
206 m_tiler
= LayerTilingData::create(tiler
.tileSize(), tiler
.hasBorderTexels() ? LayerTilingData::HasBorderTexels
: LayerTilingData::NoBorderTexels
);
210 void TiledLayerImpl::pushTileProperties(int i
, int j
, ResourceProvider::ResourceId resourceId
, const gfx::Rect
& opaqueRect
, bool contentsSwizzled
)
212 DrawableTile
* tile
= tileAt(i
, j
);
214 tile
= createTile(i
, j
);
215 tile
->setResourceId(resourceId
);
216 tile
->setOpaqueRect(opaqueRect
);
217 tile
->setContentsSwizzled(contentsSwizzled
);
220 void TiledLayerImpl::pushInvalidTile(int i
, int j
)
222 DrawableTile
* tile
= tileAt(i
, j
);
224 tile
= createTile(i
, j
);
225 tile
->setResourceId(0);
226 tile
->setOpaqueRect(gfx::Rect());
227 tile
->setContentsSwizzled(false);
230 Region
TiledLayerImpl::visibleContentOpaqueRegion() const
234 if (contentsOpaque())
235 return visibleContentRect();
236 return m_tiler
->opaqueRegionInContentRect(visibleContentRect());
239 void TiledLayerImpl::didLoseContext()
244 const char* TiledLayerImpl::layerTypeAsString() const
246 return "ContentLayer";