OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "config.h" | |
6 | |
7 #if USE(ACCELERATED_COMPOSITING) | |
8 | |
9 #include "CCTiledLayerImpl.h" | |
10 | |
11 #include "base/basictypes.h" | |
12 #include "base/stringprintf.h" | |
13 #include "CCAppendQuadsData.h" | |
14 #include "CCCheckerboardDrawQuad.h" | |
15 #include "CCDebugBorderDrawQuad.h" | |
16 #include "CCLayerTilingData.h" | |
17 #include "CCMathUtil.h" | |
18 #include "CCQuadSink.h" | |
19 #include "CCSolidColorDrawQuad.h" | |
20 #include "CCTileDrawQuad.h" | |
21 #include "FloatQuad.h" | |
22 #include "GraphicsContext3D.h" | |
23 #include "SkColor.h" | |
24 | |
25 using namespace std; | |
26 using WebKit::WebTransformationMatrix; | |
27 | |
28 namespace cc { | |
29 | |
30 static const int debugTileBorderWidth = 1; | |
31 static const int debugTileBorderAlpha = 100; | |
32 static const int debugTileBorderColorRed = 80; | |
33 static const int debugTileBorderColorGreen = 200; | |
34 static const int debugTileBorderColorBlue = 200; | |
35 static const int debugTileBorderMissingTileColorRed = 255; | |
36 static const int debugTileBorderMissingTileColorGreen = 0; | |
37 static const int debugTileBorderMissingTileColorBlue = 0; | |
38 | |
39 static const int defaultCheckerboardColorRed = 241; | |
40 static const int defaultCheckerboardColorGreen = 241; | |
41 static const int defaultCheckerboardColorBlue = 241; | |
42 static const int debugTileEvictedCheckerboardColorRed = 255; | |
43 static const int debugTileEvictedCheckerboardColorGreen = 200; | |
44 static const int debugTileEvictedCheckerboardColorBlue = 200; | |
45 static const int debugTileInvalidatedCheckerboardColorRed = 128; | |
46 static const int debugTileInvalidatedCheckerboardColorGreen = 200; | |
47 static const int debugTileInvalidatedCheckerboardColorBlue = 245; | |
48 | |
49 class DrawableTile : public CCLayerTilingData::Tile { | |
50 public: | |
51 static PassOwnPtr<DrawableTile> create() { return adoptPtr(new DrawableTile(
)); } | |
52 | |
53 CCResourceProvider::ResourceId resourceId() const { return m_resourceId; } | |
54 void setResourceId(CCResourceProvider::ResourceId resourceId) { m_resourceId
= resourceId; } | |
55 | |
56 private: | |
57 DrawableTile() : m_resourceId(0) { } | |
58 | |
59 CCResourceProvider::ResourceId m_resourceId; | |
60 | |
61 DISALLOW_COPY_AND_ASSIGN(DrawableTile); | |
62 }; | |
63 | |
64 CCTiledLayerImpl::CCTiledLayerImpl(int id) | |
65 : CCLayerImpl(id) | |
66 , m_skipsDraw(true) | |
67 , m_contentsSwizzled(false) | |
68 { | |
69 } | |
70 | |
71 CCTiledLayerImpl::~CCTiledLayerImpl() | |
72 { | |
73 } | |
74 | |
75 CCResourceProvider::ResourceId CCTiledLayerImpl::contentsResourceId() const | |
76 { | |
77 // This function is only valid for single texture layers, e.g. masks. | |
78 ASSERT(m_tiler); | |
79 ASSERT(m_tiler->numTilesX() == 1); | |
80 ASSERT(m_tiler->numTilesY() == 1); | |
81 | |
82 DrawableTile* tile = tileAt(0, 0); | |
83 CCResourceProvider::ResourceId resourceId = tile ? tile->resourceId() : 0; | |
84 return resourceId; | |
85 } | |
86 | |
87 void CCTiledLayerImpl::dumpLayerProperties(std::string* str, int indent) const | |
88 { | |
89 str->append(indentString(indent)); | |
90 base::StringAppendF(str, "skipsDraw: %d\n", (!m_tiler || m_skipsDraw)); | |
91 CCLayerImpl::dumpLayerProperties(str, indent); | |
92 } | |
93 | |
94 bool CCTiledLayerImpl::hasTileAt(int i, int j) const | |
95 { | |
96 return m_tiler->tileAt(i, j); | |
97 } | |
98 | |
99 bool CCTiledLayerImpl::hasResourceIdForTileAt(int i, int j) const | |
100 { | |
101 return hasTileAt(i, j) && tileAt(i, j)->resourceId(); | |
102 } | |
103 | |
104 DrawableTile* CCTiledLayerImpl::tileAt(int i, int j) const | |
105 { | |
106 return static_cast<DrawableTile*>(m_tiler->tileAt(i, j)); | |
107 } | |
108 | |
109 DrawableTile* CCTiledLayerImpl::createTile(int i, int j) | |
110 { | |
111 OwnPtr<DrawableTile> tile(DrawableTile::create()); | |
112 DrawableTile* addedTile = tile.get(); | |
113 m_tiler->addTile(tile.release(), i, j); | |
114 return addedTile; | |
115 } | |
116 | |
117 void CCTiledLayerImpl::appendQuads(CCQuadSink& quadSink, CCAppendQuadsData& appe
ndQuadsData) | |
118 { | |
119 const IntRect& contentRect = visibleContentRect(); | |
120 | |
121 if (!m_tiler || m_tiler->hasEmptyBounds() || contentRect.isEmpty()) | |
122 return; | |
123 | |
124 CCSharedQuadState* sharedQuadState = quadSink.useSharedQuadState(createShare
dQuadState()); | |
125 appendDebugBorderQuad(quadSink, sharedQuadState, appendQuadsData); | |
126 | |
127 int left, top, right, bottom; | |
128 m_tiler->contentRectToTileIndices(contentRect, left, top, right, bottom); | |
129 | |
130 if (hasDebugBorders()) { | |
131 for (int j = top; j <= bottom; ++j) { | |
132 for (int i = left; i <= right; ++i) { | |
133 DrawableTile* tile = tileAt(i, j); | |
134 IntRect tileRect = m_tiler->tileBounds(i, j); | |
135 SkColor borderColor; | |
136 | |
137 if (m_skipsDraw || !tile || !tile->resourceId()) | |
138 borderColor = SkColorSetARGB(debugTileBorderAlpha, debugTile
BorderMissingTileColorRed, debugTileBorderMissingTileColorGreen, debugTileBorder
MissingTileColorBlue); | |
139 else | |
140 borderColor = SkColorSetARGB(debugTileBorderAlpha, debugTile
BorderColorRed, debugTileBorderColorGreen, debugTileBorderColorBlue); | |
141 quadSink.append(CCDebugBorderDrawQuad::create(sharedQuadState, t
ileRect, borderColor, debugTileBorderWidth).PassAs<CCDrawQuad>(), appendQuadsDat
a); | |
142 } | |
143 } | |
144 } | |
145 | |
146 if (m_skipsDraw) | |
147 return; | |
148 | |
149 for (int j = top; j <= bottom; ++j) { | |
150 for (int i = left; i <= right; ++i) { | |
151 DrawableTile* tile = tileAt(i, j); | |
152 IntRect tileRect = m_tiler->tileBounds(i, j); | |
153 IntRect displayRect = tileRect; | |
154 tileRect.intersect(contentRect); | |
155 | |
156 // Skip empty tiles. | |
157 if (tileRect.isEmpty()) | |
158 continue; | |
159 | |
160 if (!tile || !tile->resourceId()) { | |
161 if (drawCheckerboardForMissingTiles()) { | |
162 SkColor defaultColor = SkColorSetRGB(defaultCheckerboardColo
rRed, defaultCheckerboardColorGreen, defaultCheckerboardColorBlue); | |
163 SkColor evictedColor = SkColorSetRGB(debugTileEvictedChecker
boardColorRed, debugTileEvictedCheckerboardColorGreen, debugTileEvictedCheckerbo
ardColorBlue); | |
164 SkColor invalidatedColor = SkColorSetRGB(debugTileInvalidate
dCheckerboardColorRed, debugTileEvictedCheckerboardColorGreen, debugTileEvictedC
heckerboardColorBlue); | |
165 | |
166 SkColor checkerColor; | |
167 if (hasDebugBorders()) | |
168 checkerColor = tile ? invalidatedColor : evictedColor; | |
169 else | |
170 checkerColor = defaultColor; | |
171 | |
172 appendQuadsData.hadMissingTiles |= quadSink.append(CCChecker
boardDrawQuad::create(sharedQuadState, tileRect, checkerColor).PassAs<CCDrawQuad
>(), appendQuadsData); | |
173 } else | |
174 appendQuadsData.hadMissingTiles |= quadSink.append(CCSolidCo
lorDrawQuad::create(sharedQuadState, tileRect, backgroundColor()).PassAs<CCDrawQ
uad>(), appendQuadsData); | |
175 continue; | |
176 } | |
177 | |
178 IntRect tileOpaqueRect = tile->opaqueRect(); | |
179 tileOpaqueRect.intersect(contentRect); | |
180 | |
181 // Keep track of how the top left has moved, so the texture can be | |
182 // offset the same amount. | |
183 IntSize displayOffset = tileRect.minXMinYCorner() - displayRect.minX
MinYCorner(); | |
184 IntPoint textureOffset = m_tiler->textureOffset(i, j) + displayOffse
t; | |
185 float tileWidth = static_cast<float>(m_tiler->tileSize().width()); | |
186 float tileHeight = static_cast<float>(m_tiler->tileSize().height()); | |
187 IntSize textureSize(tileWidth, tileHeight); | |
188 | |
189 bool clipped = false; | |
190 FloatQuad visibleContentInTargetQuad = CCMathUtil::mapQuad(drawTrans
form(), FloatQuad(visibleContentRect()), clipped); | |
191 bool isAxisAlignedInTarget = !clipped && visibleContentInTargetQuad.
isRectilinear(); | |
192 bool useAA = m_tiler->hasBorderTexels() && !isAxisAlignedInTarget; | |
193 | |
194 bool leftEdgeAA = !i && useAA; | |
195 bool topEdgeAA = !j && useAA; | |
196 bool rightEdgeAA = i == m_tiler->numTilesX() - 1 && useAA; | |
197 bool bottomEdgeAA = j == m_tiler->numTilesY() - 1 && useAA; | |
198 | |
199 const GC3Dint textureFilter = m_tiler->hasBorderTexels() ? GraphicsC
ontext3D::LINEAR : GraphicsContext3D::NEAREST; | |
200 quadSink.append(CCTileDrawQuad::create(sharedQuadState, tileRect, ti
leOpaqueRect, tile->resourceId(), textureOffset, textureSize, textureFilter, con
tentsSwizzled(), leftEdgeAA, topEdgeAA, rightEdgeAA, bottomEdgeAA).PassAs<CCDraw
Quad>(), appendQuadsData); | |
201 } | |
202 } | |
203 } | |
204 | |
205 void CCTiledLayerImpl::setTilingData(const CCLayerTilingData& tiler) | |
206 { | |
207 if (m_tiler) | |
208 m_tiler->reset(); | |
209 else | |
210 m_tiler = CCLayerTilingData::create(tiler.tileSize(), tiler.hasBorderTex
els() ? CCLayerTilingData::HasBorderTexels : CCLayerTilingData::NoBorderTexels); | |
211 *m_tiler = tiler; | |
212 } | |
213 | |
214 void CCTiledLayerImpl::pushTileProperties(int i, int j, CCResourceProvider::Reso
urceId resourceId, const IntRect& opaqueRect) | |
215 { | |
216 DrawableTile* tile = tileAt(i, j); | |
217 if (!tile) | |
218 tile = createTile(i, j); | |
219 tile->setResourceId(resourceId); | |
220 tile->setOpaqueRect(opaqueRect); | |
221 } | |
222 | |
223 void CCTiledLayerImpl::pushInvalidTile(int i, int j) | |
224 { | |
225 DrawableTile* tile = tileAt(i, j); | |
226 if (!tile) | |
227 tile = createTile(i, j); | |
228 tile->setResourceId(0); | |
229 tile->setOpaqueRect(IntRect()); | |
230 } | |
231 | |
232 Region CCTiledLayerImpl::visibleContentOpaqueRegion() const | |
233 { | |
234 if (m_skipsDraw) | |
235 return Region(); | |
236 if (contentsOpaque()) | |
237 return visibleContentRect(); | |
238 return m_tiler->opaqueRegionInContentRect(visibleContentRect()); | |
239 } | |
240 | |
241 void CCTiledLayerImpl::didLoseContext() | |
242 { | |
243 m_tiler->reset(); | |
244 } | |
245 | |
246 const char* CCTiledLayerImpl::layerTypeAsString() const | |
247 { | |
248 return "ContentLayer"; | |
249 } | |
250 | |
251 } // namespace cc | |
252 | |
253 #endif // USE(ACCELERATED_COMPOSITING) | |
OLD | NEW |