1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/basic/BasicLayersImpl.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,195 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; 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 "BasicLayersImpl.h" 1.10 +#include <new> // for operator new 1.11 +#include "Layers.h" // for Layer, etc 1.12 +#include "basic/BasicImplData.h" // for BasicImplData 1.13 +#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc 1.14 +#include "mozilla/DebugOnly.h" // for DebugOnly 1.15 +#include "mozilla/layers/CompositorTypes.h" 1.16 +#include "mozilla/layers/ISurfaceAllocator.h" 1.17 +#include "AutoMaskData.h" 1.18 + 1.19 +using namespace mozilla::gfx; 1.20 + 1.21 +namespace mozilla { 1.22 +namespace layers { 1.23 + 1.24 +bool 1.25 +GetMaskData(Layer* aMaskLayer, 1.26 + const Point& aDeviceOffset, 1.27 + AutoMoz2DMaskData* aMaskData) 1.28 +{ 1.29 + if (aMaskLayer) { 1.30 + RefPtr<SourceSurface> surface = 1.31 + static_cast<BasicImplData*>(aMaskLayer->ImplData())->GetAsSourceSurface(); 1.32 + if (surface) { 1.33 + Matrix transform; 1.34 + Matrix4x4 effectiveTransform = aMaskLayer->GetEffectiveTransform(); 1.35 + DebugOnly<bool> maskIs2D = effectiveTransform.CanDraw2D(&transform); 1.36 + NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!"); 1.37 + transform.Translate(-aDeviceOffset.x, -aDeviceOffset.y); 1.38 + aMaskData->Construct(transform, surface); 1.39 + return true; 1.40 + } 1.41 + } 1.42 + return false; 1.43 +} 1.44 + 1.45 +void 1.46 +PaintWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer) 1.47 +{ 1.48 + AutoMoz2DMaskData mask; 1.49 + if (GetMaskData(aMaskLayer, Point(), &mask)) { 1.50 + if (aOpacity < 1.0) { 1.51 + aContext->PushGroup(gfxContentType::COLOR_ALPHA); 1.52 + aContext->Paint(aOpacity); 1.53 + aContext->PopGroupToSource(); 1.54 + } 1.55 + aContext->SetMatrix(ThebesMatrix(mask.GetTransform())); 1.56 + aContext->Mask(mask.GetSurface()); 1.57 + return; 1.58 + } 1.59 + 1.60 + // if there is no mask, just paint normally 1.61 + aContext->Paint(aOpacity); 1.62 +} 1.63 + 1.64 +void 1.65 +FillRectWithMask(DrawTarget* aDT, 1.66 + const Rect& aRect, 1.67 + const Color& aColor, 1.68 + const DrawOptions& aOptions, 1.69 + SourceSurface* aMaskSource, 1.70 + const Matrix* aMaskTransform) 1.71 +{ 1.72 + if (aMaskSource && aMaskTransform) { 1.73 + aDT->PushClipRect(aRect); 1.74 + Matrix oldTransform = aDT->GetTransform(); 1.75 + 1.76 + aDT->SetTransform(*aMaskTransform); 1.77 + aDT->MaskSurface(ColorPattern(aColor), aMaskSource, Point(), aOptions); 1.78 + aDT->SetTransform(oldTransform); 1.79 + aDT->PopClip(); 1.80 + return; 1.81 + } 1.82 + 1.83 + aDT->FillRect(aRect, ColorPattern(aColor), aOptions); 1.84 +} 1.85 +void 1.86 +FillRectWithMask(DrawTarget* aDT, 1.87 + const gfx::Point& aDeviceOffset, 1.88 + const Rect& aRect, 1.89 + const Color& aColor, 1.90 + const DrawOptions& aOptions, 1.91 + Layer* aMaskLayer) 1.92 +{ 1.93 + AutoMoz2DMaskData mask; 1.94 + if (GetMaskData(aMaskLayer, aDeviceOffset, &mask)) { 1.95 + const Matrix& maskTransform = mask.GetTransform(); 1.96 + FillRectWithMask(aDT, aRect, aColor, aOptions, mask.GetSurface(), &maskTransform); 1.97 + return; 1.98 + } 1.99 + 1.100 + FillRectWithMask(aDT, aRect, aColor, aOptions); 1.101 +} 1.102 + 1.103 +void 1.104 +FillRectWithMask(DrawTarget* aDT, 1.105 + const Rect& aRect, 1.106 + SourceSurface* aSurface, 1.107 + Filter aFilter, 1.108 + const DrawOptions& aOptions, 1.109 + ExtendMode aExtendMode, 1.110 + SourceSurface* aMaskSource, 1.111 + const Matrix* aMaskTransform, 1.112 + const Matrix* aSurfaceTransform) 1.113 +{ 1.114 + if (aMaskSource && aMaskTransform) { 1.115 + aDT->PushClipRect(aRect); 1.116 + Matrix oldTransform = aDT->GetTransform(); 1.117 + 1.118 + Matrix inverseMask = *aMaskTransform; 1.119 + inverseMask.Invert(); 1.120 + 1.121 + Matrix transform = oldTransform * inverseMask; 1.122 + if (aSurfaceTransform) { 1.123 + transform = (*aSurfaceTransform) * transform; 1.124 + } 1.125 + 1.126 + SurfacePattern source(aSurface, aExtendMode, transform, aFilter); 1.127 + 1.128 + aDT->SetTransform(*aMaskTransform); 1.129 + aDT->MaskSurface(source, aMaskSource, Point(0, 0), aOptions); 1.130 + aDT->SetTransform(oldTransform); 1.131 + aDT->PopClip(); 1.132 + return; 1.133 + } 1.134 + 1.135 + aDT->FillRect(aRect, 1.136 + SurfacePattern(aSurface, aExtendMode, 1.137 + aSurfaceTransform ? (*aSurfaceTransform) : Matrix(), 1.138 + aFilter), aOptions); 1.139 +} 1.140 + 1.141 +void 1.142 +FillRectWithMask(DrawTarget* aDT, 1.143 + const gfx::Point& aDeviceOffset, 1.144 + const Rect& aRect, 1.145 + SourceSurface* aSurface, 1.146 + Filter aFilter, 1.147 + const DrawOptions& aOptions, 1.148 + Layer* aMaskLayer) 1.149 +{ 1.150 + AutoMoz2DMaskData mask; 1.151 + if (GetMaskData(aMaskLayer, aDeviceOffset, &mask)) { 1.152 + const Matrix& maskTransform = mask.GetTransform(); 1.153 + FillRectWithMask(aDT, aRect, aSurface, aFilter, aOptions, ExtendMode::CLAMP, 1.154 + mask.GetSurface(), &maskTransform); 1.155 + return; 1.156 + } 1.157 + 1.158 + FillRectWithMask(aDT, aRect, aSurface, aFilter, aOptions, ExtendMode::CLAMP); 1.159 +} 1.160 + 1.161 +BasicImplData* 1.162 +ToData(Layer* aLayer) 1.163 +{ 1.164 + return static_cast<BasicImplData*>(aLayer->ImplData()); 1.165 +} 1.166 + 1.167 +gfx::CompositionOp 1.168 +GetEffectiveOperator(Layer* aLayer) 1.169 +{ 1.170 + CompositionOp op = aLayer->GetEffectiveMixBlendMode(); 1.171 + 1.172 + if (op != CompositionOp::OP_OVER) { 1.173 + return op; 1.174 + } 1.175 + 1.176 + return ToData(aLayer)->GetOperator(); 1.177 +} 1.178 + 1.179 +ShadowableLayer* 1.180 +ToShadowable(Layer* aLayer) 1.181 +{ 1.182 + return aLayer->AsShadowableLayer(); 1.183 +} 1.184 + 1.185 +bool 1.186 +ShouldShadow(Layer* aLayer) 1.187 +{ 1.188 + if (!ToShadowable(aLayer)) { 1.189 + NS_ABORT_IF_FALSE(aLayer->GetType() == Layer::TYPE_READBACK, 1.190 + "Only expect not to shadow ReadbackLayers"); 1.191 + return false; 1.192 + } 1.193 + return true; 1.194 +} 1.195 + 1.196 + 1.197 +} 1.198 +}