diff -r 000000000000 -r 6474c204b198 gfx/layers/basic/BasicLayersImpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/layers/basic/BasicLayersImpl.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,195 @@ +/* -*- Mode: C++; tab-width: 2; 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 "BasicLayersImpl.h" +#include // for operator new +#include "Layers.h" // for Layer, etc +#include "basic/BasicImplData.h" // for BasicImplData +#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc +#include "mozilla/DebugOnly.h" // for DebugOnly +#include "mozilla/layers/CompositorTypes.h" +#include "mozilla/layers/ISurfaceAllocator.h" +#include "AutoMaskData.h" + +using namespace mozilla::gfx; + +namespace mozilla { +namespace layers { + +bool +GetMaskData(Layer* aMaskLayer, + const Point& aDeviceOffset, + AutoMoz2DMaskData* aMaskData) +{ + if (aMaskLayer) { + RefPtr surface = + static_cast(aMaskLayer->ImplData())->GetAsSourceSurface(); + if (surface) { + Matrix transform; + Matrix4x4 effectiveTransform = aMaskLayer->GetEffectiveTransform(); + DebugOnly maskIs2D = effectiveTransform.CanDraw2D(&transform); + NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!"); + transform.Translate(-aDeviceOffset.x, -aDeviceOffset.y); + aMaskData->Construct(transform, surface); + return true; + } + } + return false; +} + +void +PaintWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer) +{ + AutoMoz2DMaskData mask; + if (GetMaskData(aMaskLayer, Point(), &mask)) { + if (aOpacity < 1.0) { + aContext->PushGroup(gfxContentType::COLOR_ALPHA); + aContext->Paint(aOpacity); + aContext->PopGroupToSource(); + } + aContext->SetMatrix(ThebesMatrix(mask.GetTransform())); + aContext->Mask(mask.GetSurface()); + return; + } + + // if there is no mask, just paint normally + aContext->Paint(aOpacity); +} + +void +FillRectWithMask(DrawTarget* aDT, + const Rect& aRect, + const Color& aColor, + const DrawOptions& aOptions, + SourceSurface* aMaskSource, + const Matrix* aMaskTransform) +{ + if (aMaskSource && aMaskTransform) { + aDT->PushClipRect(aRect); + Matrix oldTransform = aDT->GetTransform(); + + aDT->SetTransform(*aMaskTransform); + aDT->MaskSurface(ColorPattern(aColor), aMaskSource, Point(), aOptions); + aDT->SetTransform(oldTransform); + aDT->PopClip(); + return; + } + + aDT->FillRect(aRect, ColorPattern(aColor), aOptions); +} +void +FillRectWithMask(DrawTarget* aDT, + const gfx::Point& aDeviceOffset, + const Rect& aRect, + const Color& aColor, + const DrawOptions& aOptions, + Layer* aMaskLayer) +{ + AutoMoz2DMaskData mask; + if (GetMaskData(aMaskLayer, aDeviceOffset, &mask)) { + const Matrix& maskTransform = mask.GetTransform(); + FillRectWithMask(aDT, aRect, aColor, aOptions, mask.GetSurface(), &maskTransform); + return; + } + + FillRectWithMask(aDT, aRect, aColor, aOptions); +} + +void +FillRectWithMask(DrawTarget* aDT, + const Rect& aRect, + SourceSurface* aSurface, + Filter aFilter, + const DrawOptions& aOptions, + ExtendMode aExtendMode, + SourceSurface* aMaskSource, + const Matrix* aMaskTransform, + const Matrix* aSurfaceTransform) +{ + if (aMaskSource && aMaskTransform) { + aDT->PushClipRect(aRect); + Matrix oldTransform = aDT->GetTransform(); + + Matrix inverseMask = *aMaskTransform; + inverseMask.Invert(); + + Matrix transform = oldTransform * inverseMask; + if (aSurfaceTransform) { + transform = (*aSurfaceTransform) * transform; + } + + SurfacePattern source(aSurface, aExtendMode, transform, aFilter); + + aDT->SetTransform(*aMaskTransform); + aDT->MaskSurface(source, aMaskSource, Point(0, 0), aOptions); + aDT->SetTransform(oldTransform); + aDT->PopClip(); + return; + } + + aDT->FillRect(aRect, + SurfacePattern(aSurface, aExtendMode, + aSurfaceTransform ? (*aSurfaceTransform) : Matrix(), + aFilter), aOptions); +} + +void +FillRectWithMask(DrawTarget* aDT, + const gfx::Point& aDeviceOffset, + const Rect& aRect, + SourceSurface* aSurface, + Filter aFilter, + const DrawOptions& aOptions, + Layer* aMaskLayer) +{ + AutoMoz2DMaskData mask; + if (GetMaskData(aMaskLayer, aDeviceOffset, &mask)) { + const Matrix& maskTransform = mask.GetTransform(); + FillRectWithMask(aDT, aRect, aSurface, aFilter, aOptions, ExtendMode::CLAMP, + mask.GetSurface(), &maskTransform); + return; + } + + FillRectWithMask(aDT, aRect, aSurface, aFilter, aOptions, ExtendMode::CLAMP); +} + +BasicImplData* +ToData(Layer* aLayer) +{ + return static_cast(aLayer->ImplData()); +} + +gfx::CompositionOp +GetEffectiveOperator(Layer* aLayer) +{ + CompositionOp op = aLayer->GetEffectiveMixBlendMode(); + + if (op != CompositionOp::OP_OVER) { + return op; + } + + return ToData(aLayer)->GetOperator(); +} + +ShadowableLayer* +ToShadowable(Layer* aLayer) +{ + return aLayer->AsShadowableLayer(); +} + +bool +ShouldShadow(Layer* aLayer) +{ + if (!ToShadowable(aLayer)) { + NS_ABORT_IF_FALSE(aLayer->GetType() == Layer::TYPE_READBACK, + "Only expect not to shadow ReadbackLayers"); + return false; + } + return true; +} + + +} +}