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 "CanvasLayerComposite.h" michael@0: #include "composite/CompositableHost.h" // for CompositableHost michael@0: #include "gfx2DGlue.h" // for ToFilter, ToMatrix4x4 michael@0: #include "GraphicsFilter.h" // for GraphicsFilter michael@0: #include "gfxUtils.h" // for gfxUtils, 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 Rect michael@0: #include "mozilla/layers/Compositor.h" // for Compositor 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 "nsPoint.h" // for nsIntPoint michael@0: #include "nsString.h" // for nsAutoCString michael@0: michael@0: using namespace mozilla; michael@0: using namespace mozilla::layers; michael@0: using namespace mozilla::gfx; michael@0: michael@0: CanvasLayerComposite::CanvasLayerComposite(LayerManagerComposite* aManager) michael@0: : CanvasLayer(aManager, nullptr) michael@0: , LayerComposite(aManager) michael@0: , mImageHost(nullptr) michael@0: { michael@0: MOZ_COUNT_CTOR(CanvasLayerComposite); michael@0: mImplData = static_cast(this); michael@0: } michael@0: michael@0: CanvasLayerComposite::~CanvasLayerComposite() michael@0: { michael@0: MOZ_COUNT_DTOR(CanvasLayerComposite); michael@0: michael@0: CleanupResources(); michael@0: } michael@0: michael@0: bool michael@0: CanvasLayerComposite::SetCompositableHost(CompositableHost* aHost) michael@0: { michael@0: switch (aHost->GetType()) { michael@0: case BUFFER_IMAGE_SINGLE: michael@0: case BUFFER_IMAGE_BUFFERED: michael@0: case COMPOSITABLE_IMAGE: michael@0: mImageHost = aHost; michael@0: return true; michael@0: default: michael@0: return false; michael@0: } michael@0: michael@0: } michael@0: michael@0: Layer* michael@0: CanvasLayerComposite::GetLayer() michael@0: { michael@0: return this; michael@0: } michael@0: michael@0: LayerRenderState michael@0: CanvasLayerComposite::GetRenderState() michael@0: { michael@0: if (mDestroyed || !mImageHost || !mImageHost->IsAttached()) { michael@0: return LayerRenderState(); michael@0: } michael@0: return mImageHost->GetRenderState(); michael@0: } michael@0: michael@0: void michael@0: CanvasLayerComposite::RenderLayer(const nsIntRect& aClipRect) michael@0: { michael@0: if (!mImageHost || !mImageHost->IsAttached()) { michael@0: return; michael@0: } michael@0: michael@0: mCompositor->MakeCurrent(); michael@0: michael@0: #ifdef MOZ_DUMP_PAINTING michael@0: if (gfxUtils::sDumpPainting) { michael@0: RefPtr surf = mImageHost->GetAsSurface(); michael@0: WriteSnapshotToDumpFile(this, surf); michael@0: } michael@0: #endif michael@0: michael@0: GraphicsFilter filter = mFilter; michael@0: #ifdef ANDROID michael@0: // Bug 691354 michael@0: // Using the LINEAR filter we get unexplained artifacts. michael@0: // Use NEAREST when no scaling is required. michael@0: Matrix matrix; michael@0: bool is2D = GetEffectiveTransform().Is2D(&matrix); michael@0: if (is2D && !ThebesMatrix(matrix).HasNonTranslationOrFlip()) { michael@0: filter = GraphicsFilter::FILTER_NEAREST; michael@0: } michael@0: #endif michael@0: michael@0: EffectChain effectChain(this); michael@0: michael@0: LayerManagerComposite::AutoAddMaskEffect autoMaskEffect(mMaskLayer, effectChain); michael@0: gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); michael@0: michael@0: mImageHost->Composite(effectChain, michael@0: GetEffectiveOpacity(), michael@0: GetEffectiveTransform(), michael@0: gfx::ToFilter(filter), michael@0: clipRect); michael@0: mImageHost->BumpFlashCounter(); michael@0: } michael@0: michael@0: CompositableHost* michael@0: CanvasLayerComposite::GetCompositableHost() michael@0: { michael@0: if ( mImageHost && mImageHost->IsAttached()) { michael@0: return mImageHost.get(); michael@0: } michael@0: michael@0: return nullptr; michael@0: } michael@0: michael@0: void michael@0: CanvasLayerComposite::CleanupResources() michael@0: { michael@0: if (mImageHost) { michael@0: mImageHost->Detach(this); michael@0: } michael@0: mImageHost = nullptr; michael@0: } michael@0: michael@0: nsACString& michael@0: CanvasLayerComposite::PrintInfo(nsACString& aTo, const char* aPrefix) michael@0: { michael@0: CanvasLayer::PrintInfo(aTo, aPrefix); michael@0: aTo += "\n"; michael@0: if (mImageHost && mImageHost->IsAttached()) { michael@0: nsAutoCString pfx(aPrefix); michael@0: pfx += " "; michael@0: mImageHost->PrintInfo(aTo, pfx.get()); michael@0: } michael@0: return aTo; michael@0: } michael@0: