LCOV - code coverage report
Current view: top level - gfx/layers/basic - BasicPaintedLayer.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 51 113 45.1 %
Date: 2017-07-14 16:53:18 Functions: 4 4 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       5             : 
       6             : #include "BasicPaintedLayer.h"
       7             : #include <stdint.h>                     // for uint32_t
       8             : #include "GeckoProfiler.h"              // for AUTO_PROFILER_LABEL
       9             : #include "ReadbackLayer.h"              // for ReadbackLayer, ReadbackSink
      10             : #include "ReadbackProcessor.h"          // for ReadbackProcessor::Update, etc
      11             : #include "RenderTrace.h"                // for RenderTraceInvalidateEnd, etc
      12             : #include "BasicLayersImpl.h"            // for AutoMaskData, etc
      13             : #include "gfxContext.h"                 // for gfxContext, etc
      14             : #include "gfxRect.h"                    // for gfxRect
      15             : #include "gfxUtils.h"                   // for gfxUtils
      16             : #include "mozilla/gfx/2D.h"             // for DrawTarget
      17             : #include "mozilla/gfx/BaseRect.h"       // for BaseRect
      18             : #include "mozilla/gfx/Matrix.h"         // for Matrix
      19             : #include "mozilla/gfx/Rect.h"           // for Rect, IntRect
      20             : #include "mozilla/gfx/Types.h"          // for Float, etc
      21             : #include "mozilla/layers/LayersTypes.h"
      22             : #include "nsCOMPtr.h"                   // for already_AddRefed
      23             : #include "nsISupportsImpl.h"            // for gfxContext::Release, etc
      24             : #include "nsPoint.h"                    // for nsIntPoint
      25             : #include "nsRect.h"                     // for mozilla::gfx::IntRect
      26             : #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl
      27             : #include "AutoMaskData.h"
      28             : #include "gfx2DGlue.h"
      29             : 
      30             : namespace mozilla {
      31             : namespace layers {
      32             : 
      33             : using namespace mozilla::gfx;
      34             : 
      35             : static nsIntRegion
      36          51 : IntersectWithClip(const nsIntRegion& aRegion, gfxContext* aContext)
      37             : {
      38          51 :   gfxRect clip = aContext->GetClipExtents();
      39          51 :   nsIntRegion result;
      40         204 :   result.And(aRegion, IntRect::RoundOut(clip.X(), clip.Y(),
      41         204 :                                         clip.Width(), clip.Height()));
      42          51 :   return result;
      43             : }
      44             : 
      45             : void
      46          51 : BasicPaintedLayer::PaintThebes(gfxContext* aContext,
      47             :                               Layer* aMaskLayer,
      48             :                               LayerManager::DrawPaintedLayerCallback aCallback,
      49             :                               void* aCallbackData)
      50             : {
      51          51 :   AUTO_PROFILER_LABEL("BasicPaintedLayer::PaintThebes", GRAPHICS);
      52             : 
      53          51 :   NS_ASSERTION(BasicManager()->InDrawing(),
      54             :                "Can only draw in drawing phase");
      55             : 
      56          51 :   float opacity = GetEffectiveOpacity();
      57          51 :   CompositionOp effectiveOperator = GetEffectiveOperator(this);
      58             : 
      59          51 :   if (!BasicManager()->IsRetained()) {
      60          51 :     ClearValidRegion();
      61          51 :     mContentClient->Clear();
      62             : 
      63         102 :     nsIntRegion toDraw = IntersectWithClip(GetLocalVisibleRegion().ToUnknownRegion(), aContext);
      64             : 
      65          51 :     RenderTraceInvalidateStart(this, "FFFF00", toDraw.GetBounds());
      66             : 
      67          51 :     if (!toDraw.IsEmpty() && !IsHidden()) {
      68          51 :       if (!aCallback) {
      69           0 :         BasicManager()->SetTransactionIncomplete();
      70           0 :         return;
      71             :       }
      72             : 
      73          51 :       aContext->Save();
      74             : 
      75          32 :       bool needsGroup = opacity != 1.0 ||
      76          83 :                         effectiveOperator != CompositionOp::OP_OVER ||
      77          51 :                         aMaskLayer;
      78         102 :       RefPtr<gfxContext> context = nullptr;
      79         102 :       BasicLayerManager::PushedGroup group;
      80          51 :       bool availableGroup = false;
      81             : 
      82          51 :       if (needsGroup) {
      83             :         availableGroup =
      84          19 :             BasicManager()->PushGroupForLayer(aContext, this, toDraw, group);
      85          19 :         if (availableGroup) {
      86          19 :           context = group.mGroupTarget;
      87             :         }
      88             :       } else {
      89          32 :         context = aContext;
      90             :       }
      91          51 :       if (context) {
      92          51 :         SetAntialiasingFlags(this, context->GetDrawTarget());
      93          51 :         aCallback(this, context, toDraw, toDraw, DrawRegionClip::NONE,
      94         102 :                   nsIntRegion(), aCallbackData);
      95             :       }
      96          51 :       if (needsGroup && availableGroup) {
      97          19 :         BasicManager()->PopGroupForLayer(group);
      98             :       }
      99             : 
     100          51 :       aContext->Restore();
     101             :     }
     102             : 
     103          51 :     RenderTraceInvalidateEnd(this, "FFFF00");
     104          51 :     return;
     105             :   }
     106             : 
     107           0 :   if (BasicManager()->IsTransactionIncomplete())
     108           0 :     return;
     109             : 
     110           0 :   gfxRect clipExtents;
     111           0 :   clipExtents = aContext->GetClipExtents();
     112             : 
     113             :   // Pull out the mask surface and transform here, because the mask
     114             :   // is internal to basic layers
     115           0 :   AutoMoz2DMaskData mask;
     116           0 :   SourceSurface* maskSurface = nullptr;
     117           0 :   Matrix maskTransform;
     118           0 :   if (GetMaskData(aMaskLayer, aContext->GetDeviceOffset(), &mask)) {
     119           0 :     maskSurface = mask.GetSurface();
     120           0 :     maskTransform = mask.GetTransform();
     121             :   }
     122             : 
     123           0 :   if (!IsHidden() && !clipExtents.IsEmpty()) {
     124           0 :     mContentClient->DrawTo(this, aContext->GetDrawTarget(), opacity,
     125             :                            effectiveOperator,
     126           0 :                            maskSurface, &maskTransform);
     127             :   }
     128             : }
     129             : 
     130             : void
     131          72 : BasicPaintedLayer::Validate(LayerManager::DrawPaintedLayerCallback aCallback,
     132             :                            void* aCallbackData,
     133             :                            ReadbackProcessor* aReadback)
     134             : {
     135          72 :   if (!mContentClient) {
     136             :     // This client will have a null Forwarder, which means it will not have
     137             :     // a ContentHost on the other side.
     138          57 :     mContentClient = new ContentClientBasic(mBackend);
     139             :   }
     140             : 
     141          72 :   if (!BasicManager()->IsRetained()) {
     142          72 :     return;
     143             :   }
     144             : 
     145           0 :   nsTArray<ReadbackProcessor::Update> readbackUpdates;
     146           0 :   if (aReadback && UsedForReadback()) {
     147           0 :     aReadback->GetPaintedLayerUpdates(this, &readbackUpdates);
     148             :   }
     149             : 
     150           0 :   uint32_t flags = 0;
     151             : #ifndef MOZ_WIDGET_ANDROID
     152           0 :   if (BasicManager()->CompositorMightResample()) {
     153           0 :     flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE;
     154             :   }
     155           0 :   if (!(flags & RotatedContentBuffer::PAINT_WILL_RESAMPLE)) {
     156           0 :     if (MayResample()) {
     157           0 :       flags |= RotatedContentBuffer::PAINT_WILL_RESAMPLE;
     158             :     }
     159             :   }
     160             : #endif
     161           0 :   if (mDrawAtomically) {
     162           0 :     flags |= RotatedContentBuffer::PAINT_NO_ROTATION;
     163             :   }
     164             :   PaintState state =
     165           0 :     mContentClient->BeginPaintBuffer(this, flags);
     166           0 :   SubtractFromValidRegion(state.mRegionToInvalidate);
     167             : 
     168           0 :   DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(state);
     169           0 :   if (target && target->IsValid()) {
     170             :     // The area that became invalid and is visible needs to be repainted
     171             :     // (this could be the whole visible area if our buffer switched
     172             :     // from RGB to RGBA, because we might need to repaint with
     173             :     // subpixel AA)
     174             :     state.mRegionToInvalidate.And(state.mRegionToInvalidate,
     175           0 :                                   GetLocalVisibleRegion().ToUnknownRegion());
     176           0 :     SetAntialiasingFlags(this, target);
     177             : 
     178           0 :     RenderTraceInvalidateStart(this, "FFFF00", state.mRegionToDraw.GetBounds());
     179             : 
     180           0 :     RefPtr<gfxContext> ctx = gfxContext::CreatePreservingTransformOrNull(target);
     181           0 :     MOZ_ASSERT(ctx); // already checked the target above
     182             : 
     183           0 :     PaintBuffer(ctx,
     184             :                 state.mRegionToDraw, state.mRegionToDraw, state.mRegionToInvalidate,
     185           0 :                 state.mDidSelfCopy,
     186             :                 state.mClip,
     187           0 :                 aCallback, aCallbackData);
     188           0 :     MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PaintThebes", this));
     189           0 :     Mutated();
     190           0 :     ctx = nullptr;
     191           0 :     mContentClient->ReturnDrawTargetToBuffer(target);
     192           0 :     target = nullptr;
     193             : 
     194           0 :     RenderTraceInvalidateEnd(this, "FFFF00");
     195             :   } else {
     196           0 :     if (target) {
     197           0 :       mContentClient->ReturnDrawTargetToBuffer(target);
     198           0 :       target = nullptr;
     199             :     }
     200             : 
     201             :     // It's possible that state.mRegionToInvalidate is nonempty here,
     202             :     // if we are shrinking the valid region to nothing. So use mRegionToDraw
     203             :     // instead.
     204           0 :     NS_WARNING_ASSERTION(
     205             :       state.mRegionToDraw.IsEmpty(),
     206             :       "No context when we have something to draw, resource exhaustion?");
     207             :   }
     208             : 
     209           0 :   for (uint32_t i = 0; i < readbackUpdates.Length(); ++i) {
     210           0 :     ReadbackProcessor::Update& update = readbackUpdates[i];
     211           0 :     nsIntPoint offset = update.mLayer->GetBackgroundLayerOffset();
     212             :     RefPtr<DrawTarget> dt =
     213           0 :       update.mLayer->GetSink()->BeginUpdate(update.mUpdateRect + offset,
     214           0 :                                             update.mSequenceCounter);
     215           0 :     if (dt) {
     216           0 :       NS_ASSERTION(GetEffectiveOpacity() == 1.0, "Should only read back opaque layers");
     217           0 :       NS_ASSERTION(!GetMaskLayer(), "Should only read back layers without masks");
     218           0 :       dt->SetTransform(dt->GetTransform().PreTranslate(offset.x, offset.y));
     219           0 :       mContentClient->DrawTo(this, dt, 1.0, CompositionOp::OP_OVER,
     220           0 :                              nullptr, nullptr);
     221           0 :       update.mLayer->GetSink()->EndUpdate(update.mUpdateRect + offset);
     222             :     }
     223             :   }
     224             : }
     225             : 
     226             : already_AddRefed<PaintedLayer>
     227         123 : BasicLayerManager::CreatePaintedLayer()
     228             : {
     229         123 :   NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
     230             : 
     231         123 :   BackendType backend = gfxPlatform::GetPlatform()->GetDefaultContentBackend();
     232             : 
     233         123 :   if (mDefaultTarget) {
     234           0 :     backend = mDefaultTarget->GetDrawTarget()->GetBackendType();
     235         123 :   } else if (mType == BLM_WIDGET) {
     236           0 :     backend = gfxPlatform::GetPlatform()->GetContentBackendFor(LayersBackend::LAYERS_BASIC);
     237             :   }
     238             : 
     239         246 :   RefPtr<PaintedLayer> layer = new BasicPaintedLayer(this, backend);
     240         246 :   return layer.forget();
     241             : }
     242             : 
     243             : } // namespace layers
     244             : } // namespace mozilla

Generated by: LCOV version 1.13