gfx/layers/basic/BasicLayersImpl.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "BasicLayersImpl.h"
     7 #include <new>                          // for operator new
     8 #include "Layers.h"                     // for Layer, etc
     9 #include "basic/BasicImplData.h"        // for BasicImplData
    10 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
    11 #include "mozilla/DebugOnly.h"          // for DebugOnly
    12 #include "mozilla/layers/CompositorTypes.h"
    13 #include "mozilla/layers/ISurfaceAllocator.h"
    14 #include "AutoMaskData.h"
    16 using namespace mozilla::gfx;
    18 namespace mozilla {
    19 namespace layers {
    21 bool
    22 GetMaskData(Layer* aMaskLayer,
    23             const Point& aDeviceOffset,
    24             AutoMoz2DMaskData* aMaskData)
    25 {
    26   if (aMaskLayer) {
    27     RefPtr<SourceSurface> surface =
    28       static_cast<BasicImplData*>(aMaskLayer->ImplData())->GetAsSourceSurface();
    29     if (surface) {
    30       Matrix transform;
    31       Matrix4x4 effectiveTransform = aMaskLayer->GetEffectiveTransform();
    32       DebugOnly<bool> maskIs2D = effectiveTransform.CanDraw2D(&transform);
    33       NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
    34       transform.Translate(-aDeviceOffset.x, -aDeviceOffset.y);
    35       aMaskData->Construct(transform, surface);
    36       return true;
    37     }
    38   }
    39   return false;
    40 }
    42 void
    43 PaintWithMask(gfxContext* aContext, float aOpacity, Layer* aMaskLayer)
    44 {
    45   AutoMoz2DMaskData mask;
    46   if (GetMaskData(aMaskLayer, Point(), &mask)) {
    47     if (aOpacity < 1.0) {
    48       aContext->PushGroup(gfxContentType::COLOR_ALPHA);
    49       aContext->Paint(aOpacity);
    50       aContext->PopGroupToSource();
    51     }
    52     aContext->SetMatrix(ThebesMatrix(mask.GetTransform()));
    53     aContext->Mask(mask.GetSurface());
    54     return;
    55   }
    57   // if there is no mask, just paint normally
    58   aContext->Paint(aOpacity);
    59 }
    61 void
    62 FillRectWithMask(DrawTarget* aDT,
    63                  const Rect& aRect,
    64                  const Color& aColor,
    65                  const DrawOptions& aOptions,
    66                  SourceSurface* aMaskSource,
    67                  const Matrix* aMaskTransform)
    68 {
    69   if (aMaskSource && aMaskTransform) {
    70     aDT->PushClipRect(aRect);
    71     Matrix oldTransform = aDT->GetTransform();
    73     aDT->SetTransform(*aMaskTransform);
    74     aDT->MaskSurface(ColorPattern(aColor), aMaskSource, Point(), aOptions);
    75     aDT->SetTransform(oldTransform);
    76     aDT->PopClip();
    77     return;
    78   }
    80   aDT->FillRect(aRect, ColorPattern(aColor), aOptions);
    81 }
    82 void
    83 FillRectWithMask(DrawTarget* aDT,
    84                  const gfx::Point& aDeviceOffset,
    85                  const Rect& aRect,
    86                  const Color& aColor,
    87                  const DrawOptions& aOptions,
    88                  Layer* aMaskLayer)
    89 {
    90   AutoMoz2DMaskData mask;
    91   if (GetMaskData(aMaskLayer, aDeviceOffset, &mask)) {
    92     const Matrix& maskTransform = mask.GetTransform();
    93     FillRectWithMask(aDT, aRect, aColor, aOptions, mask.GetSurface(), &maskTransform);
    94     return;
    95   }
    97   FillRectWithMask(aDT, aRect, aColor, aOptions);
    98 }
   100 void
   101 FillRectWithMask(DrawTarget* aDT,
   102                  const Rect& aRect,
   103                  SourceSurface* aSurface,
   104                  Filter aFilter,
   105                  const DrawOptions& aOptions,
   106                  ExtendMode aExtendMode,
   107                  SourceSurface* aMaskSource,
   108                  const Matrix* aMaskTransform,
   109                  const Matrix* aSurfaceTransform)
   110 {
   111   if (aMaskSource && aMaskTransform) {
   112     aDT->PushClipRect(aRect);
   113     Matrix oldTransform = aDT->GetTransform();
   115     Matrix inverseMask = *aMaskTransform;
   116     inverseMask.Invert();
   118     Matrix transform = oldTransform * inverseMask;
   119     if (aSurfaceTransform) {
   120       transform = (*aSurfaceTransform) * transform;
   121     }
   123     SurfacePattern source(aSurface, aExtendMode, transform, aFilter);
   125     aDT->SetTransform(*aMaskTransform);
   126     aDT->MaskSurface(source, aMaskSource, Point(0, 0), aOptions);
   127     aDT->SetTransform(oldTransform);
   128     aDT->PopClip();
   129     return;
   130   }
   132   aDT->FillRect(aRect,
   133                 SurfacePattern(aSurface, aExtendMode,
   134                                aSurfaceTransform ? (*aSurfaceTransform) : Matrix(),
   135                                aFilter), aOptions);
   136 }
   138 void
   139 FillRectWithMask(DrawTarget* aDT,
   140                  const gfx::Point& aDeviceOffset,
   141                  const Rect& aRect,
   142                  SourceSurface* aSurface,
   143                  Filter aFilter,
   144                  const DrawOptions& aOptions,
   145                  Layer* aMaskLayer)
   146 {
   147   AutoMoz2DMaskData mask;
   148   if (GetMaskData(aMaskLayer, aDeviceOffset, &mask)) {
   149     const Matrix& maskTransform = mask.GetTransform();
   150     FillRectWithMask(aDT, aRect, aSurface, aFilter, aOptions, ExtendMode::CLAMP,
   151                      mask.GetSurface(), &maskTransform);
   152     return;
   153   }
   155   FillRectWithMask(aDT, aRect, aSurface, aFilter, aOptions, ExtendMode::CLAMP);
   156 }
   158 BasicImplData*
   159 ToData(Layer* aLayer)
   160 {
   161   return static_cast<BasicImplData*>(aLayer->ImplData());
   162 }
   164 gfx::CompositionOp
   165 GetEffectiveOperator(Layer* aLayer)
   166 {
   167   CompositionOp op = aLayer->GetEffectiveMixBlendMode();
   169   if (op != CompositionOp::OP_OVER) {
   170     return op;
   171   }
   173   return ToData(aLayer)->GetOperator();
   174 }
   176 ShadowableLayer*
   177 ToShadowable(Layer* aLayer)
   178 {
   179   return aLayer->AsShadowableLayer();
   180 }
   182 bool
   183 ShouldShadow(Layer* aLayer)
   184 {
   185   if (!ToShadowable(aLayer)) {
   186     NS_ABORT_IF_FALSE(aLayer->GetType() == Layer::TYPE_READBACK,
   187                       "Only expect not to shadow ReadbackLayers");
   188     return false;
   189   }
   190   return true;
   191 }
   194 }
   195 }

mercurial