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