| 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 "CCRenderSurface.h" | |
| 10 | |
| 11 #include "base/stringprintf.h" | |
| 12 #include "CCDamageTracker.h" | |
| 13 #include "CCDebugBorderDrawQuad.h" | |
| 14 #include "CCDelegatedRendererLayerImpl.h" | |
| 15 #include "CCLayerImpl.h" | |
| 16 #include "CCMathUtil.h" | |
| 17 #include "CCQuadSink.h" | |
| 18 #include "CCRenderPass.h" | |
| 19 #include "CCRenderPassDrawQuad.h" | |
| 20 #include "CCRenderPassSink.h" | |
| 21 #include "CCSharedQuadState.h" | |
| 22 #include <public/WebTransformationMatrix.h> | |
| 23 | |
| 24 using WebKit::WebTransformationMatrix; | |
| 25 | |
| 26 namespace cc { | |
| 27 | |
| 28 static const int debugSurfaceBorderWidth = 2; | |
| 29 static const int debugSurfaceBorderAlpha = 100; | |
| 30 static const int debugSurfaceBorderColorRed = 0; | |
| 31 static const int debugSurfaceBorderColorGreen = 0; | |
| 32 static const int debugSurfaceBorderColorBlue = 255; | |
| 33 static const int debugReplicaBorderColorRed = 160; | |
| 34 static const int debugReplicaBorderColorGreen = 0; | |
| 35 static const int debugReplicaBorderColorBlue = 255; | |
| 36 | |
| 37 CCRenderSurface::CCRenderSurface(CCLayerImpl* owningLayer) | |
| 38 : m_owningLayer(owningLayer) | |
| 39 , m_surfacePropertyChanged(false) | |
| 40 , m_drawOpacity(1) | |
| 41 , m_drawOpacityIsAnimating(false) | |
| 42 , m_targetSurfaceTransformsAreAnimating(false) | |
| 43 , m_screenSpaceTransformsAreAnimating(false) | |
| 44 , m_nearestAncestorThatMovesPixels(0) | |
| 45 , m_targetRenderSurfaceLayerIndexHistory(0) | |
| 46 , m_currentLayerIndexHistory(0) | |
| 47 { | |
| 48 m_damageTracker = CCDamageTracker::create(); | |
| 49 } | |
| 50 | |
| 51 CCRenderSurface::~CCRenderSurface() | |
| 52 { | |
| 53 } | |
| 54 | |
| 55 FloatRect CCRenderSurface::drawableContentRect() const | |
| 56 { | |
| 57 FloatRect drawableContentRect = CCMathUtil::mapClippedRect(m_drawTransform,
m_contentRect); | |
| 58 if (m_owningLayer->hasReplica()) | |
| 59 drawableContentRect.unite(CCMathUtil::mapClippedRect(m_replicaDrawTransf
orm, m_contentRect)); | |
| 60 | |
| 61 return drawableContentRect; | |
| 62 } | |
| 63 | |
| 64 std::string CCRenderSurface::name() const | |
| 65 { | |
| 66 return base::StringPrintf("RenderSurface(id=%i,owner=%s)", m_owningLayer->id
(), m_owningLayer->debugName().data()); | |
| 67 } | |
| 68 | |
| 69 static std::string indentString(int indent) | |
| 70 { | |
| 71 std::string str; | |
| 72 for (int i = 0; i != indent; ++i) | |
| 73 str.append(" "); | |
| 74 return str; | |
| 75 } | |
| 76 | |
| 77 void CCRenderSurface::dumpSurface(std::string* str, int indent) const | |
| 78 { | |
| 79 std::string indentStr = indentString(indent); | |
| 80 str->append(indentStr); | |
| 81 base::StringAppendF(str, "%s\n", name().data()); | |
| 82 | |
| 83 indentStr.append(" "); | |
| 84 str->append(indentStr); | |
| 85 base::StringAppendF(str, "contentRect: (%d, %d, %d, %d)\n", m_contentRect.x(
), m_contentRect.y(), m_contentRect.width(), m_contentRect.height()); | |
| 86 | |
| 87 str->append(indentStr); | |
| 88 base::StringAppendF(str, "drawTransform: %f, %f, %f, %f, %f, %f, %f, %f, %f,
%f, %f, %f, %f, %f, %f, %f\n", | |
| 89 m_drawTransform.m11(), m_drawTransform.m12(), m_drawTransform.m13(), m_d
rawTransform.m14(), | |
| 90 m_drawTransform.m21(), m_drawTransform.m22(), m_drawTransform.m23(), m_d
rawTransform.m24(), | |
| 91 m_drawTransform.m31(), m_drawTransform.m32(), m_drawTransform.m33(), m_d
rawTransform.m34(), | |
| 92 m_drawTransform.m41(), m_drawTransform.m42(), m_drawTransform.m43(), m_d
rawTransform.m44()); | |
| 93 | |
| 94 str->append(indentStr); | |
| 95 base::StringAppendF(str, "damageRect is pos(%f, %f), size(%f, %f)\n", | |
| 96 m_damageTracker->currentDamageRect().x(), m_damageTracker->currentDamage
Rect().y(), | |
| 97 m_damageTracker->currentDamageRect().width(), m_damageTracker->currentDa
mageRect().height()); | |
| 98 } | |
| 99 | |
| 100 int CCRenderSurface::owningLayerId() const | |
| 101 { | |
| 102 return m_owningLayer ? m_owningLayer->id() : 0; | |
| 103 } | |
| 104 | |
| 105 | |
| 106 void CCRenderSurface::setClipRect(const IntRect& clipRect) | |
| 107 { | |
| 108 if (m_clipRect == clipRect) | |
| 109 return; | |
| 110 | |
| 111 m_surfacePropertyChanged = true; | |
| 112 m_clipRect = clipRect; | |
| 113 } | |
| 114 | |
| 115 bool CCRenderSurface::contentsChanged() const | |
| 116 { | |
| 117 return !m_damageTracker->currentDamageRect().isEmpty(); | |
| 118 } | |
| 119 | |
| 120 void CCRenderSurface::setContentRect(const IntRect& contentRect) | |
| 121 { | |
| 122 if (m_contentRect == contentRect) | |
| 123 return; | |
| 124 | |
| 125 m_surfacePropertyChanged = true; | |
| 126 m_contentRect = contentRect; | |
| 127 } | |
| 128 | |
| 129 bool CCRenderSurface::surfacePropertyChanged() const | |
| 130 { | |
| 131 // Surface property changes are tracked as follows: | |
| 132 // | |
| 133 // - m_surfacePropertyChanged is flagged when the clipRect or contentRect ch
ange. As | |
| 134 // of now, these are the only two properties that can be affected by desce
ndant layers. | |
| 135 // | |
| 136 // - all other property changes come from the owning layer (or some ancestor
layer | |
| 137 // that propagates its change to the owning layer). | |
| 138 // | |
| 139 ASSERT(m_owningLayer); | |
| 140 return m_surfacePropertyChanged || m_owningLayer->layerPropertyChanged(); | |
| 141 } | |
| 142 | |
| 143 bool CCRenderSurface::surfacePropertyChangedOnlyFromDescendant() const | |
| 144 { | |
| 145 return m_surfacePropertyChanged && !m_owningLayer->layerPropertyChanged(); | |
| 146 } | |
| 147 | |
| 148 void CCRenderSurface::addContributingDelegatedRenderPassLayer(CCLayerImpl* layer
) | |
| 149 { | |
| 150 ASSERT(std::find(m_layerList.begin(), m_layerList.end(), layer) != m_layerLi
st.end()); | |
| 151 CCDelegatedRendererLayerImpl* delegatedRendererLayer = static_cast<CCDelegat
edRendererLayerImpl*>(layer); | |
| 152 m_contributingDelegatedRenderPassLayerList.push_back(delegatedRendererLayer)
; | |
| 153 } | |
| 154 | |
| 155 void CCRenderSurface::clearLayerLists() | |
| 156 { | |
| 157 m_layerList.clear(); | |
| 158 m_contributingDelegatedRenderPassLayerList.clear(); | |
| 159 } | |
| 160 | |
| 161 static inline IntRect computeClippedRectInTarget(const CCLayerImpl* owningLayer) | |
| 162 { | |
| 163 ASSERT(owningLayer->parent()); | |
| 164 | |
| 165 const CCLayerImpl* renderTarget = owningLayer->parent()->renderTarget(); | |
| 166 const CCRenderSurface* self = owningLayer->renderSurface(); | |
| 167 | |
| 168 IntRect clippedRectInTarget = self->clipRect(); | |
| 169 if (owningLayer->backgroundFilters().hasFilterThatMovesPixels()) { | |
| 170 // If the layer has background filters that move pixels, we cannot sciss
or as tightly. | |
| 171 // FIXME: this should be able to be a tighter scissor, perhaps expanded
by the filter outsets? | |
| 172 clippedRectInTarget = renderTarget->renderSurface()->contentRect(); | |
| 173 } else if (clippedRectInTarget.isEmpty()) { | |
| 174 // For surfaces, empty clipRect means that the surface does not clip any
thing. | |
| 175 clippedRectInTarget = enclosingIntRect(intersection(renderTarget->render
Surface()->contentRect(), self->drawableContentRect())); | |
| 176 } else | |
| 177 clippedRectInTarget.intersect(enclosingIntRect(self->drawableContentRect
())); | |
| 178 return clippedRectInTarget; | |
| 179 } | |
| 180 | |
| 181 CCRenderPass::Id CCRenderSurface::renderPassId() | |
| 182 { | |
| 183 int layerId = m_owningLayer->id(); | |
| 184 int subId = 0; | |
| 185 ASSERT(layerId > 0); | |
| 186 return CCRenderPass::Id(layerId, subId); | |
| 187 } | |
| 188 | |
| 189 void CCRenderSurface::appendRenderPasses(CCRenderPassSink& passSink) | |
| 190 { | |
| 191 for (size_t i = 0; i < m_contributingDelegatedRenderPassLayerList.size(); ++
i) | |
| 192 m_contributingDelegatedRenderPassLayerList[i]->appendContributingRenderP
asses(passSink); | |
| 193 | |
| 194 scoped_ptr<CCRenderPass> pass = CCRenderPass::create(renderPassId(), m_conte
ntRect, m_screenSpaceTransform); | |
| 195 pass->setDamageRect(m_damageTracker->currentDamageRect()); | |
| 196 pass->setFilters(m_owningLayer->filters()); | |
| 197 pass->setBackgroundFilters(m_owningLayer->backgroundFilters()); | |
| 198 passSink.appendRenderPass(pass.Pass()); | |
| 199 } | |
| 200 | |
| 201 void CCRenderSurface::appendQuads(CCQuadSink& quadSink, CCAppendQuadsData& appen
dQuadsData, bool forReplica, CCRenderPass::Id renderPassId) | |
| 202 { | |
| 203 ASSERT(!forReplica || m_owningLayer->hasReplica()); | |
| 204 | |
| 205 IntRect clippedRectInTarget = computeClippedRectInTarget(m_owningLayer); | |
| 206 bool isOpaque = false; | |
| 207 const WebTransformationMatrix& drawTransform = forReplica ? m_replicaDrawTra
nsform : m_drawTransform; | |
| 208 CCSharedQuadState* sharedQuadState = quadSink.useSharedQuadState(CCSharedQua
dState::create(drawTransform, m_contentRect, clippedRectInTarget, m_drawOpacity,
isOpaque).Pass()); | |
| 209 | |
| 210 if (m_owningLayer->hasDebugBorders()) { | |
| 211 int red = forReplica ? debugReplicaBorderColorRed : debugSurfaceBorderCo
lorRed; | |
| 212 int green = forReplica ? debugReplicaBorderColorGreen : debugSurfaceBor
derColorGreen; | |
| 213 int blue = forReplica ? debugReplicaBorderColorBlue : debugSurfaceBorder
ColorBlue; | |
| 214 SkColor color = SkColorSetARGB(debugSurfaceBorderAlpha, red, green, blue
); | |
| 215 quadSink.append(CCDebugBorderDrawQuad::create(sharedQuadState, contentRe
ct(), color, debugSurfaceBorderWidth).PassAs<CCDrawQuad>(), appendQuadsData); | |
| 216 } | |
| 217 | |
| 218 // FIXME: By using the same RenderSurface for both the content and its refle
ction, | |
| 219 // it's currently not possible to apply a separate mask to the reflection la
yer | |
| 220 // or correctly handle opacity in reflections (opacity must be applied after
drawing | |
| 221 // both the layer and its reflection). The solution is to introduce yet anot
her RenderSurface | |
| 222 // to draw the layer and its reflection in. For now we only apply a separate
reflection | |
| 223 // mask if the contents don't have a mask of their own. | |
| 224 CCLayerImpl* maskLayer = m_owningLayer->maskLayer(); | |
| 225 if (maskLayer && (!maskLayer->drawsContent() || maskLayer->bounds().isEmpty(
))) | |
| 226 maskLayer = 0; | |
| 227 | |
| 228 if (!maskLayer && forReplica) { | |
| 229 maskLayer = m_owningLayer->replicaLayer()->maskLayer(); | |
| 230 if (maskLayer && (!maskLayer->drawsContent() || maskLayer->bounds().isEm
pty())) | |
| 231 maskLayer = 0; | |
| 232 } | |
| 233 | |
| 234 float maskTexCoordScaleX = 1; | |
| 235 float maskTexCoordScaleY = 1; | |
| 236 float maskTexCoordOffsetX = 1; | |
| 237 float maskTexCoordOffsetY = 1; | |
| 238 if (maskLayer) { | |
| 239 maskTexCoordScaleX = static_cast<float>(contentRect().width()) / maskLay
er->contentBounds().width(); | |
| 240 maskTexCoordScaleY = static_cast<float>(contentRect().height()) / maskLa
yer->contentBounds().height(); | |
| 241 maskTexCoordOffsetX = static_cast<float>(contentRect().x()) / contentRec
t().width() * maskTexCoordScaleX; | |
| 242 maskTexCoordOffsetY = static_cast<float>(contentRect().y()) / contentRec
t().height() * maskTexCoordScaleY; | |
| 243 } | |
| 244 | |
| 245 CCResourceProvider::ResourceId maskResourceId = maskLayer ? maskLayer->conte
ntsResourceId() : 0; | |
| 246 IntRect contentsChangedSinceLastFrame = contentsChanged() ? m_contentRect :
IntRect(); | |
| 247 | |
| 248 quadSink.append(CCRenderPassDrawQuad::create(sharedQuadState, contentRect(),
renderPassId, forReplica, maskResourceId, contentsChangedSinceLastFrame, | |
| 249 maskTexCoordScaleX, maskTexCoor
dScaleY, maskTexCoordOffsetX, maskTexCoordOffsetY).PassAs<CCDrawQuad>(), appendQ
uadsData); | |
| 250 } | |
| 251 | |
| 252 } | |
| 253 #endif // USE(ACCELERATED_COMPOSITING) | |
| OLD | NEW |