1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/composite/ContainerLayerComposite.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,524 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "ContainerLayerComposite.h" 1.10 +#include <algorithm> // for min 1.11 +#include "FrameMetrics.h" // for FrameMetrics 1.12 +#include "Units.h" // for LayerRect, LayerPixel, etc 1.13 +#include "gfx2DGlue.h" // for ToMatrix4x4 1.14 +#include "gfx3DMatrix.h" // for gfx3DMatrix 1.15 +#include "gfxPrefs.h" // for gfxPrefs 1.16 +#include "gfxUtils.h" // for gfxUtils, etc 1.17 +#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc 1.18 +#include "mozilla/RefPtr.h" // for RefPtr 1.19 +#include "mozilla/gfx/BaseRect.h" // for BaseRect 1.20 +#include "mozilla/gfx/Matrix.h" // for Matrix4x4 1.21 +#include "mozilla/gfx/Point.h" // for Point, IntPoint 1.22 +#include "mozilla/gfx/Rect.h" // for IntRect, Rect 1.23 +#include "mozilla/layers/Compositor.h" // for Compositor, etc 1.24 +#include "mozilla/layers/CompositorTypes.h" // for DIAGNOSTIC_CONTAINER 1.25 +#include "mozilla/layers/Effects.h" // for Effect, EffectChain, etc 1.26 +#include "mozilla/layers/TextureHost.h" // for CompositingRenderTarget 1.27 +#include "mozilla/mozalloc.h" // for operator delete, etc 1.28 +#include "nsAutoPtr.h" // for nsRefPtr 1.29 +#include "nsDebug.h" // for NS_ASSERTION 1.30 +#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc 1.31 +#include "nsISupportsUtils.h" // for NS_ADDREF, NS_RELEASE 1.32 +#include "nsPoint.h" // for nsIntPoint 1.33 +#include "nsRect.h" // for nsIntRect 1.34 +#include "nsRegion.h" // for nsIntRegion 1.35 +#include "nsTArray.h" // for nsAutoTArray 1.36 +#include "TextRenderer.h" // for TextRenderer 1.37 +#include <vector> 1.38 + 1.39 +namespace mozilla { 1.40 +namespace layers { 1.41 + 1.42 +/** 1.43 + * Returns a rectangle of content painted opaquely by aLayer. Very consertative; 1.44 + * bails by returning an empty rect in any tricky situations. 1.45 + */ 1.46 +static nsIntRect 1.47 +GetOpaqueRect(Layer* aLayer) 1.48 +{ 1.49 + nsIntRect result; 1.50 + gfx::Matrix matrix; 1.51 + bool is2D = aLayer->GetBaseTransform().Is2D(&matrix); 1.52 + 1.53 + // Just bail if there's anything difficult to handle. 1.54 + if (!is2D || aLayer->GetMaskLayer() || 1.55 + aLayer->GetEffectiveOpacity() != 1.0f || 1.56 + matrix.HasNonIntegerTranslation()) { 1.57 + return result; 1.58 + } 1.59 + 1.60 + if (aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE) { 1.61 + result = aLayer->GetEffectiveVisibleRegion().GetLargestRectangle(); 1.62 + } else { 1.63 + // Drill down into RefLayers because that's what we particularly care about; 1.64 + // layer construction for aLayer will not have known about the opaqueness 1.65 + // of any RefLayer subtrees. 1.66 + RefLayer* refLayer = aLayer->AsRefLayer(); 1.67 + if (refLayer && refLayer->GetFirstChild()) { 1.68 + result = GetOpaqueRect(refLayer->GetFirstChild()); 1.69 + } 1.70 + } 1.71 + 1.72 + // Translate our opaque region to cover the child 1.73 + gfx::Point point = matrix.GetTranslation(); 1.74 + result.MoveBy(static_cast<int>(point.x), static_cast<int>(point.y)); 1.75 + 1.76 + const nsIntRect* clipRect = aLayer->GetEffectiveClipRect(); 1.77 + if (clipRect) { 1.78 + result.IntersectRect(result, *clipRect); 1.79 + } 1.80 + 1.81 + return result; 1.82 +} 1.83 + 1.84 +struct LayerVelocityUserData : public LayerUserData { 1.85 +public: 1.86 + LayerVelocityUserData() { 1.87 + MOZ_COUNT_CTOR(LayerVelocityUserData); 1.88 + } 1.89 + ~LayerVelocityUserData() { 1.90 + MOZ_COUNT_DTOR(LayerVelocityUserData); 1.91 + } 1.92 + 1.93 + struct VelocityData { 1.94 + VelocityData(TimeStamp frameTime, int scrollX, int scrollY) 1.95 + : mFrameTime(frameTime) 1.96 + , mPoint(scrollX, scrollY) 1.97 + {} 1.98 + 1.99 + TimeStamp mFrameTime; 1.100 + gfx::Point mPoint; 1.101 + }; 1.102 + std::vector<VelocityData> mData; 1.103 +}; 1.104 + 1.105 +static gfx::Point GetScrollData(Layer* aLayer) { 1.106 + gfx::Matrix matrix; 1.107 + if (aLayer->GetLocalTransform().Is2D(&matrix)) { 1.108 + return matrix.GetTranslation(); 1.109 + } 1.110 + 1.111 + gfx::Point origin; 1.112 + return origin; 1.113 +} 1.114 + 1.115 +static void DrawLayerInfo(const nsIntRect& aClipRect, 1.116 + LayerManagerComposite* aManager, 1.117 + Layer* aLayer) 1.118 +{ 1.119 + 1.120 + if (aLayer->GetType() == Layer::LayerType::TYPE_CONTAINER) { 1.121 + // XXX - should figure out a way to render this, but for now this 1.122 + // is hard to do, since it will often get superimposed over the first 1.123 + // child of the layer, which is bad. 1.124 + return; 1.125 + } 1.126 + 1.127 + nsAutoCString layerInfo; 1.128 + aLayer->PrintInfo(layerInfo, ""); 1.129 + 1.130 + nsIntRegion visibleRegion = aLayer->GetVisibleRegion(); 1.131 + 1.132 + uint32_t maxWidth = std::min<uint32_t>(visibleRegion.GetBounds().width, 500); 1.133 + 1.134 + nsIntPoint topLeft = visibleRegion.GetBounds().TopLeft(); 1.135 + aManager->GetTextRenderer()->RenderText(layerInfo.get(), gfx::IntPoint(topLeft.x, topLeft.y), 1.136 + aLayer->GetEffectiveTransform(), 16, 1.137 + maxWidth); 1.138 + 1.139 +} 1.140 + 1.141 +static LayerVelocityUserData* GetVelocityData(Layer* aLayer) { 1.142 + static char sLayerVelocityUserDataKey; 1.143 + void* key = reinterpret_cast<void*>(&sLayerVelocityUserDataKey); 1.144 + if (!aLayer->HasUserData(key)) { 1.145 + LayerVelocityUserData* newData = new LayerVelocityUserData(); 1.146 + aLayer->SetUserData(key, newData); 1.147 + } 1.148 + 1.149 + return static_cast<LayerVelocityUserData*>(aLayer->GetUserData(key)); 1.150 +} 1.151 + 1.152 +static void DrawVelGraph(const nsIntRect& aClipRect, 1.153 + LayerManagerComposite* aManager, 1.154 + Layer* aLayer) { 1.155 + Compositor* compositor = aManager->GetCompositor(); 1.156 + gfx::Rect clipRect(aClipRect.x, aClipRect.y, 1.157 + aClipRect.width, aClipRect.height); 1.158 + 1.159 + TimeStamp now = TimeStamp::Now(); 1.160 + LayerVelocityUserData* velocityData = GetVelocityData(aLayer); 1.161 + 1.162 + if (velocityData->mData.size() >= 1 && 1.163 + now > velocityData->mData[velocityData->mData.size() - 1].mFrameTime + 1.164 + TimeDuration::FromMilliseconds(200)) { 1.165 + // clear stale data 1.166 + velocityData->mData.clear(); 1.167 + } 1.168 + 1.169 + const gfx::Point layerTransform = GetScrollData(aLayer); 1.170 + velocityData->mData.push_back( 1.171 + LayerVelocityUserData::VelocityData(now, 1.172 + static_cast<int>(layerTransform.x), static_cast<int>(layerTransform.y))); 1.173 + 1.174 + // TODO: dump to file 1.175 + // XXX: Uncomment these lines to enable ScrollGraph logging. This is 1.176 + // useful for HVGA phones or to output the data to accurate 1.177 + // graphing software. 1.178 + // printf_stderr("ScrollGraph (%p): %f, %f\n", 1.179 + // aLayer, layerTransform.x, layerTransform.y); 1.180 + 1.181 + // Keep a circular buffer of 100. 1.182 + size_t circularBufferSize = 100; 1.183 + if (velocityData->mData.size() > circularBufferSize) { 1.184 + velocityData->mData.erase(velocityData->mData.begin()); 1.185 + } 1.186 + 1.187 + if (velocityData->mData.size() == 1) { 1.188 + return; 1.189 + } 1.190 + 1.191 + // Clear and disable the graph when it's flat 1.192 + for (size_t i = 1; i < velocityData->mData.size(); i++) { 1.193 + if (velocityData->mData[i - 1].mPoint != velocityData->mData[i].mPoint) { 1.194 + break; 1.195 + } 1.196 + if (i == velocityData->mData.size() - 1) { 1.197 + velocityData->mData.clear(); 1.198 + return; 1.199 + } 1.200 + } 1.201 + 1.202 + if (aLayer->GetEffectiveVisibleRegion().GetBounds().width < 300 || 1.203 + aLayer->GetEffectiveVisibleRegion().GetBounds().height < 300) { 1.204 + // Don't want a graph for smaller layers 1.205 + return; 1.206 + } 1.207 + 1.208 + aManager->SetDebugOverlayWantsNextFrame(true); 1.209 + 1.210 + const gfx::Matrix4x4& transform = aLayer->GetEffectiveTransform(); 1.211 + nsIntRect bounds = aLayer->GetEffectiveVisibleRegion().GetBounds(); 1.212 + gfx::Rect graphBounds = gfx::Rect(bounds.x, bounds.y, 1.213 + bounds.width, bounds.height); 1.214 + gfx::Rect graphRect = gfx::Rect(bounds.x, bounds.y, 200, 100); 1.215 + 1.216 + float opacity = 1.0; 1.217 + EffectChain effects; 1.218 + effects.mPrimaryEffect = new EffectSolidColor(gfx::Color(0.2f,0,0,1)); 1.219 + compositor->DrawQuad(graphRect, 1.220 + clipRect, 1.221 + effects, 1.222 + opacity, 1.223 + transform); 1.224 + 1.225 + std::vector<gfx::Point> graph; 1.226 + int yScaleFactor = 3; 1.227 + for (int32_t i = (int32_t)velocityData->mData.size() - 2; i >= 0; i--) { 1.228 + const gfx::Point& p1 = velocityData->mData[i+1].mPoint; 1.229 + const gfx::Point& p2 = velocityData->mData[i].mPoint; 1.230 + int vel = sqrt((p1.x - p2.x) * (p1.x - p2.x) + 1.231 + (p1.y - p2.y) * (p1.y - p2.y)); 1.232 + graph.push_back( 1.233 + gfx::Point(bounds.x + graphRect.width / circularBufferSize * i, 1.234 + graphBounds.y + graphRect.height - vel/yScaleFactor)); 1.235 + } 1.236 + 1.237 + compositor->DrawLines(graph, clipRect, gfx::Color(0,1,0,1), 1.238 + opacity, transform); 1.239 +} 1.240 + 1.241 +// ContainerRender is shared between RefLayer and ContainerLayer 1.242 +template<class ContainerT> void 1.243 +ContainerRender(ContainerT* aContainer, 1.244 + LayerManagerComposite* aManager, 1.245 + const nsIntRect& aClipRect) 1.246 +{ 1.247 + /** 1.248 + * Setup our temporary surface for rendering the contents of this container. 1.249 + */ 1.250 + RefPtr<CompositingRenderTarget> surface; 1.251 + 1.252 + Compositor* compositor = aManager->GetCompositor(); 1.253 + 1.254 + RefPtr<CompositingRenderTarget> previousTarget = compositor->GetCurrentRenderTarget(); 1.255 + 1.256 + nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); 1.257 + 1.258 + aContainer->mSupportsComponentAlphaChildren = false; 1.259 + 1.260 + float opacity = aContainer->GetEffectiveOpacity(); 1.261 + 1.262 + bool needsSurface = aContainer->UseIntermediateSurface(); 1.263 + if (needsSurface) { 1.264 + SurfaceInitMode mode = INIT_MODE_CLEAR; 1.265 + bool surfaceCopyNeeded = false; 1.266 + gfx::IntRect surfaceRect = gfx::IntRect(visibleRect.x, visibleRect.y, 1.267 + visibleRect.width, visibleRect.height); 1.268 + gfx::IntPoint sourcePoint = gfx::IntPoint(visibleRect.x, visibleRect.y); 1.269 + // we're about to create a framebuffer backed by textures to use as an intermediate 1.270 + // surface. What to do if its size (as given by framebufferRect) would exceed the 1.271 + // maximum texture size supported by the GL? The present code chooses the compromise 1.272 + // of just clamping the framebuffer's size to the max supported size. 1.273 + // This gives us a lower resolution rendering of the intermediate surface (children layers). 1.274 + // See bug 827170 for a discussion. 1.275 + int32_t maxTextureSize = compositor->GetMaxTextureSize(); 1.276 + surfaceRect.width = std::min(maxTextureSize, surfaceRect.width); 1.277 + surfaceRect.height = std::min(maxTextureSize, surfaceRect.height); 1.278 + if (aContainer->GetEffectiveVisibleRegion().GetNumRects() == 1 && 1.279 + (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE)) 1.280 + { 1.281 + // don't need a background, we're going to paint all opaque stuff 1.282 + aContainer->mSupportsComponentAlphaChildren = true; 1.283 + mode = INIT_MODE_NONE; 1.284 + } else { 1.285 + const gfx::Matrix4x4& transform3D = aContainer->GetEffectiveTransform(); 1.286 + gfx::Matrix transform; 1.287 + // If we have an opaque ancestor layer, then we can be sure that 1.288 + // all the pixels we draw into are either opaque already or will be 1.289 + // covered by something opaque. Otherwise copying up the background is 1.290 + // not safe. 1.291 + if (ContainerLayer::HasOpaqueAncestorLayer(aContainer) && 1.292 + transform3D.Is2D(&transform) && !ThebesMatrix(transform).HasNonIntegerTranslation()) { 1.293 + surfaceCopyNeeded = gfxPrefs::ComponentAlphaEnabled(); 1.294 + sourcePoint.x += transform._31; 1.295 + sourcePoint.y += transform._32; 1.296 + aContainer->mSupportsComponentAlphaChildren 1.297 + = gfxPrefs::ComponentAlphaEnabled(); 1.298 + } 1.299 + } 1.300 + 1.301 + sourcePoint -= compositor->GetCurrentRenderTarget()->GetOrigin(); 1.302 + if (surfaceCopyNeeded) { 1.303 + surface = compositor->CreateRenderTargetFromSource(surfaceRect, previousTarget, sourcePoint); 1.304 + } else { 1.305 + surface = compositor->CreateRenderTarget(surfaceRect, mode); 1.306 + } 1.307 + 1.308 + if (!surface) { 1.309 + return; 1.310 + } 1.311 + 1.312 + compositor->SetRenderTarget(surface); 1.313 + } else { 1.314 + surface = previousTarget; 1.315 + aContainer->mSupportsComponentAlphaChildren = (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE) || 1.316 + (aContainer->GetParent() && aContainer->GetParent()->SupportsComponentAlphaChildren()); 1.317 + } 1.318 + 1.319 + nsAutoTArray<Layer*, 12> children; 1.320 + aContainer->SortChildrenBy3DZOrder(children); 1.321 + 1.322 + /** 1.323 + * Render this container's contents. 1.324 + */ 1.325 + for (uint32_t i = 0; i < children.Length(); i++) { 1.326 + LayerComposite* layerToRender = static_cast<LayerComposite*>(children.ElementAt(i)->ImplData()); 1.327 + 1.328 + if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty() && 1.329 + !layerToRender->GetLayer()->AsContainerLayer()) { 1.330 + continue; 1.331 + } 1.332 + 1.333 + nsIntRect clipRect = layerToRender->GetLayer()-> 1.334 + CalculateScissorRect(aClipRect, &aManager->GetWorldTransform()); 1.335 + if (clipRect.IsEmpty()) { 1.336 + continue; 1.337 + } 1.338 + 1.339 + nsIntRegion savedVisibleRegion; 1.340 + bool restoreVisibleRegion = false; 1.341 + if (i + 1 < children.Length() && 1.342 + layerToRender->GetLayer()->GetEffectiveTransform().IsIdentity()) { 1.343 + LayerComposite* nextLayer = static_cast<LayerComposite*>(children.ElementAt(i + 1)->ImplData()); 1.344 + nsIntRect nextLayerOpaqueRect; 1.345 + if (nextLayer && nextLayer->GetLayer()) { 1.346 + nextLayerOpaqueRect = GetOpaqueRect(nextLayer->GetLayer()); 1.347 + } 1.348 + if (!nextLayerOpaqueRect.IsEmpty()) { 1.349 + savedVisibleRegion = layerToRender->GetShadowVisibleRegion(); 1.350 + nsIntRegion visibleRegion; 1.351 + visibleRegion.Sub(savedVisibleRegion, nextLayerOpaqueRect); 1.352 + if (visibleRegion.IsEmpty()) { 1.353 + continue; 1.354 + } 1.355 + layerToRender->SetShadowVisibleRegion(visibleRegion); 1.356 + restoreVisibleRegion = true; 1.357 + } 1.358 + } 1.359 + 1.360 + if (layerToRender->HasLayerBeenComposited()) { 1.361 + // Composer2D will compose this layer so skip GPU composition 1.362 + // this time & reset composition flag for next composition phase 1.363 + layerToRender->SetLayerComposited(false); 1.364 + nsIntRect clearRect = layerToRender->GetClearRect(); 1.365 + if (!clearRect.IsEmpty()) { 1.366 + // Clear layer's visible rect on FrameBuffer with transparent pixels 1.367 + gfx::Rect fbRect(clearRect.x, clearRect.y, clearRect.width, clearRect.height); 1.368 + compositor->ClearRect(fbRect); 1.369 + layerToRender->SetClearRect(nsIntRect(0, 0, 0, 0)); 1.370 + } 1.371 + } else { 1.372 + layerToRender->RenderLayer(clipRect); 1.373 + } 1.374 + 1.375 + if (restoreVisibleRegion) { 1.376 + // Restore the region in case it's not covered by opaque content next time 1.377 + layerToRender->SetShadowVisibleRegion(savedVisibleRegion); 1.378 + } 1.379 + 1.380 + if (gfxPrefs::LayersScrollGraph()) { 1.381 + DrawVelGraph(clipRect, aManager, layerToRender->GetLayer()); 1.382 + } 1.383 + 1.384 + if (gfxPrefs::DrawLayerInfo()) { 1.385 + DrawLayerInfo(clipRect, aManager, layerToRender->GetLayer()); 1.386 + } 1.387 + // invariant: our GL context should be current here, I don't think we can 1.388 + // assert it though 1.389 + } 1.390 + 1.391 + if (needsSurface) { 1.392 + // Unbind the current surface and rebind the previous one. 1.393 +#ifdef MOZ_DUMP_PAINTING 1.394 + if (gfxUtils::sDumpPainting) { 1.395 + RefPtr<gfx::DataSourceSurface> surf = surface->Dump(aManager->GetCompositor()); 1.396 + WriteSnapshotToDumpFile(aContainer, surf); 1.397 + } 1.398 +#endif 1.399 + 1.400 + compositor->SetRenderTarget(previousTarget); 1.401 + EffectChain effectChain(aContainer); 1.402 + LayerManagerComposite::AutoAddMaskEffect autoMaskEffect(aContainer->GetMaskLayer(), 1.403 + effectChain, 1.404 + !aContainer->GetTransform().CanDraw2D()); 1.405 + 1.406 + effectChain.mPrimaryEffect = new EffectRenderTarget(surface); 1.407 + 1.408 + gfx::Rect rect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height); 1.409 + gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); 1.410 + aManager->GetCompositor()->DrawQuad(rect, clipRect, effectChain, opacity, 1.411 + aContainer->GetEffectiveTransform()); 1.412 + } 1.413 + 1.414 + if (aContainer->GetFrameMetrics().IsScrollable()) { 1.415 + const FrameMetrics& frame = aContainer->GetFrameMetrics(); 1.416 + LayerRect layerBounds = ParentLayerRect(frame.mCompositionBounds) * ParentLayerToLayerScale(1.0); 1.417 + gfx::Rect rect(layerBounds.x, layerBounds.y, layerBounds.width, layerBounds.height); 1.418 + gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); 1.419 + aManager->GetCompositor()->DrawDiagnostics(DIAGNOSTIC_CONTAINER, 1.420 + rect, clipRect, 1.421 + aContainer->GetEffectiveTransform()); 1.422 + } 1.423 +} 1.424 + 1.425 +ContainerLayerComposite::ContainerLayerComposite(LayerManagerComposite *aManager) 1.426 + : ContainerLayer(aManager, nullptr) 1.427 + , LayerComposite(aManager) 1.428 +{ 1.429 + MOZ_COUNT_CTOR(ContainerLayerComposite); 1.430 + mImplData = static_cast<LayerComposite*>(this); 1.431 +} 1.432 + 1.433 +ContainerLayerComposite::~ContainerLayerComposite() 1.434 +{ 1.435 + MOZ_COUNT_DTOR(ContainerLayerComposite); 1.436 + 1.437 + // We don't Destroy() on destruction here because this destructor 1.438 + // can be called after remote content has crashed, and it may not be 1.439 + // safe to free the IPC resources of our children. Those resources 1.440 + // are automatically cleaned up by IPDL-generated code. 1.441 + // 1.442 + // In the common case of normal shutdown, either 1.443 + // LayerManagerComposite::Destroy(), a parent 1.444 + // *ContainerLayerComposite::Destroy(), or Disconnect() will trigger 1.445 + // cleanup of our resources. 1.446 + while (mFirstChild) { 1.447 + RemoveChild(mFirstChild); 1.448 + } 1.449 +} 1.450 + 1.451 +void 1.452 +ContainerLayerComposite::Destroy() 1.453 +{ 1.454 + if (!mDestroyed) { 1.455 + while (mFirstChild) { 1.456 + static_cast<LayerComposite*>(GetFirstChild()->ImplData())->Destroy(); 1.457 + RemoveChild(mFirstChild); 1.458 + } 1.459 + mDestroyed = true; 1.460 + } 1.461 +} 1.462 + 1.463 +LayerComposite* 1.464 +ContainerLayerComposite::GetFirstChildComposite() 1.465 +{ 1.466 + if (!mFirstChild) { 1.467 + return nullptr; 1.468 + } 1.469 + return static_cast<LayerComposite*>(mFirstChild->ImplData()); 1.470 +} 1.471 + 1.472 +void 1.473 +ContainerLayerComposite::RenderLayer(const nsIntRect& aClipRect) 1.474 +{ 1.475 + ContainerRender(this, mCompositeManager, aClipRect); 1.476 +} 1.477 + 1.478 +void 1.479 +ContainerLayerComposite::CleanupResources() 1.480 +{ 1.481 + for (Layer* l = GetFirstChild(); l; l = l->GetNextSibling()) { 1.482 + LayerComposite* layerToCleanup = static_cast<LayerComposite*>(l->ImplData()); 1.483 + layerToCleanup->CleanupResources(); 1.484 + } 1.485 +} 1.486 + 1.487 +RefLayerComposite::RefLayerComposite(LayerManagerComposite* aManager) 1.488 + : RefLayer(aManager, nullptr) 1.489 + , LayerComposite(aManager) 1.490 +{ 1.491 + mImplData = static_cast<LayerComposite*>(this); 1.492 +} 1.493 + 1.494 +RefLayerComposite::~RefLayerComposite() 1.495 +{ 1.496 + Destroy(); 1.497 +} 1.498 + 1.499 +void 1.500 +RefLayerComposite::Destroy() 1.501 +{ 1.502 + MOZ_ASSERT(!mFirstChild); 1.503 + mDestroyed = true; 1.504 +} 1.505 + 1.506 +LayerComposite* 1.507 +RefLayerComposite::GetFirstChildComposite() 1.508 +{ 1.509 + if (!mFirstChild) { 1.510 + return nullptr; 1.511 + } 1.512 + return static_cast<LayerComposite*>(mFirstChild->ImplData()); 1.513 +} 1.514 + 1.515 +void 1.516 +RefLayerComposite::RenderLayer(const nsIntRect& aClipRect) 1.517 +{ 1.518 + ContainerRender(this, mCompositeManager, aClipRect); 1.519 +} 1.520 + 1.521 +void 1.522 +RefLayerComposite::CleanupResources() 1.523 +{ 1.524 +} 1.525 + 1.526 +} /* layers */ 1.527 +} /* mozilla */