michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "ThebesLayerComposite.h" michael@0: #include "CompositableHost.h" // for TiledLayerProperties, etc michael@0: #include "FrameMetrics.h" // for FrameMetrics michael@0: #include "Units.h" // for CSSRect, LayerPixel, etc michael@0: #include "gfx2DGlue.h" // for ToMatrix4x4 michael@0: #include "gfxUtils.h" // for gfxUtils, etc michael@0: #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc michael@0: #include "mozilla/gfx/Matrix.h" // for Matrix4x4 michael@0: #include "mozilla/gfx/Point.h" // for Point michael@0: #include "mozilla/gfx/Rect.h" // for RoundedToInt, Rect michael@0: #include "mozilla/gfx/Types.h" // for Filter::Filter::LINEAR michael@0: #include "mozilla/layers/Compositor.h" // for Compositor michael@0: #include "mozilla/layers/ContentHost.h" // for ContentHost michael@0: #include "mozilla/layers/Effects.h" // for EffectChain michael@0: #include "mozilla/mozalloc.h" // for operator delete michael@0: #include "nsAString.h" michael@0: #include "nsAutoPtr.h" // for nsRefPtr michael@0: #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc michael@0: #include "nsMathUtils.h" // for NS_lround michael@0: #include "nsPoint.h" // for nsIntPoint michael@0: #include "nsRect.h" // for nsIntRect michael@0: #include "nsSize.h" // for nsIntSize michael@0: #include "nsString.h" // for nsAutoCString michael@0: #include "TextRenderer.h" michael@0: #include "GeckoProfiler.h" michael@0: michael@0: namespace mozilla { michael@0: namespace layers { michael@0: michael@0: class TiledLayerComposer; michael@0: michael@0: ThebesLayerComposite::ThebesLayerComposite(LayerManagerComposite *aManager) michael@0: : ThebesLayer(aManager, nullptr) michael@0: , LayerComposite(aManager) michael@0: , mBuffer(nullptr) michael@0: , mRequiresTiledProperties(false) michael@0: { michael@0: MOZ_COUNT_CTOR(ThebesLayerComposite); michael@0: mImplData = static_cast(this); michael@0: } michael@0: michael@0: ThebesLayerComposite::~ThebesLayerComposite() michael@0: { michael@0: MOZ_COUNT_DTOR(ThebesLayerComposite); michael@0: CleanupResources(); michael@0: } michael@0: michael@0: bool michael@0: ThebesLayerComposite::SetCompositableHost(CompositableHost* aHost) michael@0: { michael@0: switch (aHost->GetType()) { michael@0: case BUFFER_CONTENT_INC: michael@0: case BUFFER_TILED: michael@0: case COMPOSITABLE_CONTENT_SINGLE: michael@0: case COMPOSITABLE_CONTENT_DOUBLE: michael@0: mBuffer = static_cast(aHost); michael@0: return true; michael@0: default: michael@0: return false; michael@0: } michael@0: } michael@0: michael@0: void michael@0: ThebesLayerComposite::Disconnect() michael@0: { michael@0: Destroy(); michael@0: } michael@0: michael@0: void michael@0: ThebesLayerComposite::Destroy() michael@0: { michael@0: if (!mDestroyed) { michael@0: CleanupResources(); michael@0: mDestroyed = true; michael@0: } michael@0: } michael@0: michael@0: Layer* michael@0: ThebesLayerComposite::GetLayer() michael@0: { michael@0: return this; michael@0: } michael@0: michael@0: TiledLayerComposer* michael@0: ThebesLayerComposite::GetTiledLayerComposer() michael@0: { michael@0: if (!mBuffer) { michael@0: return nullptr; michael@0: } michael@0: MOZ_ASSERT(mBuffer->IsAttached()); michael@0: return mBuffer->AsTiledLayerComposer(); michael@0: } michael@0: michael@0: LayerRenderState michael@0: ThebesLayerComposite::GetRenderState() michael@0: { michael@0: if (!mBuffer || !mBuffer->IsAttached() || mDestroyed) { michael@0: return LayerRenderState(); michael@0: } michael@0: return mBuffer->GetRenderState(); michael@0: } michael@0: michael@0: void michael@0: ThebesLayerComposite::RenderLayer(const nsIntRect& aClipRect) michael@0: { michael@0: if (!mBuffer || !mBuffer->IsAttached()) { michael@0: return; michael@0: } michael@0: PROFILER_LABEL("ThebesLayerComposite", "RenderLayer"); michael@0: michael@0: MOZ_ASSERT(mBuffer->GetCompositor() == mCompositeManager->GetCompositor() && michael@0: mBuffer->GetLayer() == this, michael@0: "buffer is corrupted"); michael@0: michael@0: gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); michael@0: michael@0: #ifdef MOZ_DUMP_PAINTING michael@0: if (gfxUtils::sDumpPainting) { michael@0: RefPtr surf = mBuffer->GetAsSurface(); michael@0: if (surf) { michael@0: WriteSnapshotToDumpFile(this, surf); michael@0: } michael@0: } michael@0: #endif michael@0: michael@0: EffectChain effectChain(this); michael@0: LayerManagerComposite::AutoAddMaskEffect autoMaskEffect(mMaskLayer, effectChain); michael@0: michael@0: nsIntRegion visibleRegion = GetEffectiveVisibleRegion(); michael@0: michael@0: TiledLayerProperties tiledLayerProps; michael@0: if (mRequiresTiledProperties) { michael@0: tiledLayerProps.mVisibleRegion = visibleRegion; michael@0: tiledLayerProps.mEffectiveResolution = GetEffectiveResolution(); michael@0: tiledLayerProps.mValidRegion = mValidRegion; michael@0: } michael@0: michael@0: mBuffer->SetPaintWillResample(MayResample()); michael@0: michael@0: mBuffer->Composite(effectChain, michael@0: GetEffectiveOpacity(), michael@0: GetEffectiveTransform(), michael@0: gfx::Filter::LINEAR, michael@0: clipRect, michael@0: &visibleRegion, michael@0: mRequiresTiledProperties ? &tiledLayerProps michael@0: : nullptr); michael@0: mBuffer->BumpFlashCounter(); michael@0: michael@0: if (mRequiresTiledProperties) { michael@0: mValidRegion = tiledLayerProps.mValidRegion; michael@0: } michael@0: michael@0: mCompositeManager->GetCompositor()->MakeCurrent(); michael@0: } michael@0: michael@0: CompositableHost* michael@0: ThebesLayerComposite::GetCompositableHost() michael@0: { michael@0: if (mBuffer && mBuffer->IsAttached()) { michael@0: return mBuffer.get(); michael@0: } michael@0: michael@0: return nullptr; michael@0: } michael@0: michael@0: void michael@0: ThebesLayerComposite::CleanupResources() michael@0: { michael@0: if (mBuffer) { michael@0: mBuffer->Detach(this); michael@0: } michael@0: mBuffer = nullptr; michael@0: } michael@0: michael@0: CSSToScreenScale michael@0: ThebesLayerComposite::GetEffectiveResolution() michael@0: { michael@0: for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) { michael@0: const FrameMetrics& metrics = parent->GetFrameMetrics(); michael@0: if (metrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID) { michael@0: return metrics.GetZoom(); michael@0: } michael@0: } michael@0: michael@0: return CSSToScreenScale(1.0); michael@0: } michael@0: michael@0: nsACString& michael@0: ThebesLayerComposite::PrintInfo(nsACString& aTo, const char* aPrefix) michael@0: { michael@0: ThebesLayer::PrintInfo(aTo, aPrefix); michael@0: aTo += "\n"; michael@0: if (mBuffer && mBuffer->IsAttached()) { michael@0: nsAutoCString pfx(aPrefix); michael@0: pfx += " "; michael@0: mBuffer->PrintInfo(aTo, pfx.get()); michael@0: } michael@0: return aTo; michael@0: } michael@0: michael@0: } /* layers */ michael@0: } /* mozilla */