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"
24 // Temporary diagnostic.
25 static bool safeToDeleteDrawableTile
= false;
27 class DrawableTile
: public LayerTilingData::Tile
{
29 static scoped_ptr
<DrawableTile
> create() { return make_scoped_ptr(new DrawableTile()); }
31 virtual ~DrawableTile() { CHECK(safeToDeleteDrawableTile
); }
33 ResourceProvider::ResourceId
resourceId() const { return m_resourceId
; }
34 void setResourceId(ResourceProvider::ResourceId resourceId
) { m_resourceId
= resourceId
; }
35 bool contentsSwizzled() { return m_contentsSwizzled
; }
36 void setContentsSwizzled(bool contentsSwizzled
) { m_contentsSwizzled
= contentsSwizzled
; }
41 , m_contentsSwizzled(false) { }
43 ResourceProvider::ResourceId m_resourceId
;
44 bool m_contentsSwizzled
;
46 DISALLOW_COPY_AND_ASSIGN(DrawableTile
);
49 TiledLayerImpl::TiledLayerImpl(LayerTreeImpl
* treeImpl
, int id
)
50 : LayerImpl(treeImpl
, id
)
55 TiledLayerImpl::~TiledLayerImpl()
57 safeToDeleteDrawableTile
= true;
60 safeToDeleteDrawableTile
= false;
63 ResourceProvider::ResourceId
TiledLayerImpl::contentsResourceId() const
65 // This function is only valid for single texture layers, e.g. masks.
67 DCHECK(m_tiler
->numTilesX() == 1);
68 DCHECK(m_tiler
->numTilesY() == 1);
70 DrawableTile
* tile
= tileAt(0, 0);
71 ResourceProvider::ResourceId resourceId
= tile
? tile
->resourceId() : 0;
75 void TiledLayerImpl::dumpLayerProperties(std::string
* str
, int indent
) const
77 str
->append(indentString(indent
));
78 base::StringAppendF(str
, "skipsDraw: %d\n", (!m_tiler
|| m_skipsDraw
));
79 LayerImpl::dumpLayerProperties(str
, indent
);
82 bool TiledLayerImpl::hasTileAt(int i
, int j
) const
84 return m_tiler
->tileAt(i
, j
);
87 bool TiledLayerImpl::hasResourceIdForTileAt(int i
, int j
) const
89 return hasTileAt(i
, j
) && tileAt(i
, j
)->resourceId();
92 DrawableTile
* TiledLayerImpl::tileAt(int i
, int j
) const
94 return static_cast<DrawableTile
*>(m_tiler
->tileAt(i
, j
));
97 DrawableTile
* TiledLayerImpl::createTile(int i
, int j
)
99 scoped_ptr
<DrawableTile
> tile(DrawableTile::create());
100 DrawableTile
* addedTile
= tile
.get();
101 m_tiler
->addTile(tile
.PassAs
<LayerTilingData::Tile
>(), i
, j
);
103 // Temporary diagnostic checks.
110 void TiledLayerImpl::getDebugBorderProperties(SkColor
* color
, float* width
) const
112 *color
= DebugColors::TiledContentLayerBorderColor();
113 *width
= DebugColors::TiledContentLayerBorderWidth(layerTreeImpl());
116 void TiledLayerImpl::appendQuads(QuadSink
& quadSink
, AppendQuadsData
& appendQuadsData
)
118 const gfx::Rect
& contentRect
= visibleContentRect();
120 if (!m_tiler
|| m_tiler
->hasEmptyBounds() || contentRect
.IsEmpty())
123 SharedQuadState
* sharedQuadState
= quadSink
.useSharedQuadState(createSharedQuadState());
124 appendDebugBorderQuad(quadSink
, sharedQuadState
, appendQuadsData
);
126 int left
, top
, right
, bottom
;
127 m_tiler
->contentRectToTileIndices(contentRect
, left
, top
, right
, bottom
);
129 if (showDebugBorders()) {
130 for (int j
= top
; j
<= bottom
; ++j
) {
131 for (int i
= left
; i
<= right
; ++i
) {
132 DrawableTile
* tile
= tileAt(i
, j
);
133 gfx::Rect tileRect
= m_tiler
->tileBounds(i
, j
);
137 if (m_skipsDraw
|| !tile
|| !tile
->resourceId()) {
138 borderColor
= DebugColors::MissingTileBorderColor();
139 borderWidth
= DebugColors::MissingTileBorderWidth(layerTreeImpl());
141 borderColor
= DebugColors::TileBorderColor();
142 borderWidth
= DebugColors::TileBorderWidth(layerTreeImpl());
144 scoped_ptr
<DebugBorderDrawQuad
> debugBorderQuad
= DebugBorderDrawQuad::Create();
145 debugBorderQuad
->SetNew(sharedQuadState
, tileRect
, borderColor
, borderWidth
);
146 quadSink
.append(debugBorderQuad
.PassAs
<DrawQuad
>(), appendQuadsData
);
154 for (int j
= top
; j
<= bottom
; ++j
) {
155 for (int i
= left
; i
<= right
; ++i
) {
156 DrawableTile
* tile
= tileAt(i
, j
);
157 gfx::Rect tileRect
= m_tiler
->tileBounds(i
, j
);
158 gfx::Rect displayRect
= tileRect
;
159 tileRect
.Intersect(contentRect
);
162 if (tileRect
.IsEmpty())
165 if (!tile
|| !tile
->resourceId()) {
166 if (drawCheckerboardForMissingTiles()) {
167 SkColor checkerColor
;
168 if (showDebugBorders())
169 checkerColor
= tile
? DebugColors::InvalidatedTileCheckerboardColor() : DebugColors::EvictedTileCheckerboardColor();
171 checkerColor
= DebugColors::DefaultCheckerboardColor();
173 scoped_ptr
<CheckerboardDrawQuad
> checkerboardQuad
= CheckerboardDrawQuad::Create();
174 checkerboardQuad
->SetNew(sharedQuadState
, tileRect
, checkerColor
);
175 if (quadSink
.append(checkerboardQuad
.PassAs
<DrawQuad
>(), appendQuadsData
))
176 appendQuadsData
.numMissingTiles
++;
178 scoped_ptr
<SolidColorDrawQuad
> solidColorQuad
= SolidColorDrawQuad::Create();
179 solidColorQuad
->SetNew(sharedQuadState
, tileRect
, backgroundColor());
180 if (quadSink
.append(solidColorQuad
.PassAs
<DrawQuad
>(), appendQuadsData
))
181 appendQuadsData
.numMissingTiles
++;
186 gfx::Rect tileOpaqueRect
= contentsOpaque() ? tileRect
: gfx::IntersectRects(tile
->opaqueRect(), contentRect
);
188 // Keep track of how the top left has moved, so the texture can be
189 // offset the same amount.
190 gfx::Vector2d displayOffset
= tileRect
.origin() - displayRect
.origin();
191 gfx::Vector2d textureOffset
= m_tiler
->textureOffset(i
, j
) + displayOffset
;
192 gfx::RectF texCoordRect
= gfx::RectF(tileRect
.size()) + textureOffset
;
194 float tileWidth
= static_cast<float>(m_tiler
->tileSize().width());
195 float tileHeight
= static_cast<float>(m_tiler
->tileSize().height());
196 gfx::Size
textureSize(tileWidth
, tileHeight
);
198 bool clipped
= false;
199 gfx::QuadF visibleContentInTargetQuad
= MathUtil::mapQuad(drawTransform(), gfx::QuadF(visibleContentRect()), clipped
);
200 bool isAxisAlignedInTarget
= !clipped
&& visibleContentInTargetQuad
.IsRectilinear();
201 bool useAA
= m_tiler
->hasBorderTexels() && !isAxisAlignedInTarget
;
203 bool leftEdgeAA
= !i
&& useAA
;
204 bool topEdgeAA
= !j
&& useAA
;
205 bool rightEdgeAA
= i
== m_tiler
->numTilesX() - 1 && useAA
;
206 bool bottomEdgeAA
= j
== m_tiler
->numTilesY() - 1 && useAA
;
208 scoped_ptr
<TileDrawQuad
> quad
= TileDrawQuad::Create();
209 quad
->SetNew(sharedQuadState
, tileRect
, tileOpaqueRect
, tile
->resourceId(), texCoordRect
, textureSize
, tile
->contentsSwizzled(), leftEdgeAA
, topEdgeAA
, rightEdgeAA
, bottomEdgeAA
);
210 quadSink
.append(quad
.PassAs
<DrawQuad
>(), appendQuadsData
);
215 void TiledLayerImpl::setTilingData(const LayerTilingData
& tiler
)
217 safeToDeleteDrawableTile
= true;
222 m_tiler
= LayerTilingData::create(tiler
.tileSize(), tiler
.hasBorderTexels() ? LayerTilingData::HasBorderTexels
: LayerTilingData::NoBorderTexels
);
225 safeToDeleteDrawableTile
= false;
228 void TiledLayerImpl::pushTileProperties(int i
, int j
, ResourceProvider::ResourceId resourceId
, const gfx::Rect
& opaqueRect
, bool contentsSwizzled
)
230 DrawableTile
* tile
= tileAt(i
, j
);
232 tile
= createTile(i
, j
);
233 tile
->setResourceId(resourceId
);
234 tile
->setOpaqueRect(opaqueRect
);
235 tile
->setContentsSwizzled(contentsSwizzled
);
238 void TiledLayerImpl::pushInvalidTile(int i
, int j
)
240 DrawableTile
* tile
= tileAt(i
, j
);
242 tile
= createTile(i
, j
);
243 tile
->setResourceId(0);
244 tile
->setOpaqueRect(gfx::Rect());
245 tile
->setContentsSwizzled(false);
248 Region
TiledLayerImpl::visibleContentOpaqueRegion() const
252 if (contentsOpaque())
253 return visibleContentRect();
254 return m_tiler
->opaqueRegionInContentRect(visibleContentRect());
257 void TiledLayerImpl::didLoseOutputSurface()
259 safeToDeleteDrawableTile
= true;
260 // Temporary diagnostic check.
263 safeToDeleteDrawableTile
= false;
266 const char* TiledLayerImpl::layerTypeAsString() const
268 return "ContentLayer";