LCOV - code coverage report
Current view: top level - image - SurfacePipe.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 53 81 65.4 %
Date: 2017-07-14 16:53:18 Functions: 7 9 77.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "SurfacePipe.h"
       8             : 
       9             : #include <utility>
      10             : 
      11             : #include "mozilla/ClearOnShutdown.h"
      12             : #include "mozilla/DebugOnly.h"
      13             : #include "Decoder.h"
      14             : 
      15             : namespace mozilla {
      16             : namespace image {
      17             : 
      18             : using namespace gfx;
      19             : 
      20             : using std::min;
      21             : 
      22           3 : /* static */ UniquePtr<NullSurfaceSink> NullSurfaceSink::sSingleton;
      23             : 
      24             : /* static */ NullSurfaceSink*
      25         310 : NullSurfaceSink::Singleton()
      26             : {
      27         310 :   if (!sSingleton) {
      28           3 :     MOZ_ASSERT(NS_IsMainThread());
      29           3 :     sSingleton = MakeUnique<NullSurfaceSink>();
      30           3 :     ClearOnShutdown(&sSingleton);
      31             : 
      32           6 :     DebugOnly<nsresult> rv = sSingleton->Configure(NullSurfaceConfig { });
      33           3 :     MOZ_ASSERT(NS_SUCCEEDED(rv), "Couldn't configure a NullSurfaceSink?");
      34             :   }
      35             : 
      36         310 :   return sSingleton.get();
      37             : }
      38             : 
      39             : nsresult
      40           3 : NullSurfaceSink::Configure(const NullSurfaceConfig& aConfig)
      41             : {
      42             :   // Note that the choice of uint32_t as the pixel size here is more or less
      43             :   // arbitrary, since you cannot write to a NullSurfaceSink anyway, but uint32_t
      44             :   // is a natural choice since most SurfacePipes will be for BGRA/BGRX surfaces.
      45           3 :   ConfigureFilter(IntSize(), sizeof(uint32_t));
      46           3 :   return NS_OK;
      47             : }
      48             : 
      49             : Maybe<SurfaceInvalidRect>
      50        1538 : AbstractSurfaceSink::TakeInvalidRect()
      51             : {
      52        1538 :   if (mInvalidRect.IsEmpty()) {
      53           0 :     return Nothing();
      54             :   }
      55             : 
      56        1538 :   SurfaceInvalidRect invalidRect;
      57        1538 :   invalidRect.mInputSpaceRect = invalidRect.mOutputSpaceRect = mInvalidRect;
      58             : 
      59             :   // Forget about the invalid rect we're returning.
      60        1538 :   mInvalidRect = IntRect();
      61             : 
      62        1538 :   return Some(invalidRect);
      63             : }
      64             : 
      65             : uint8_t*
      66          48 : AbstractSurfaceSink::DoResetToFirstRow()
      67             : {
      68          48 :   mRow = 0;
      69          48 :   return GetRowPointer();
      70             : }
      71             : 
      72             : uint8_t*
      73        1543 : AbstractSurfaceSink::DoAdvanceRow()
      74             : {
      75        1543 :   if (mRow >= uint32_t(InputSize().height)) {
      76           0 :     return nullptr;
      77             :   }
      78             : 
      79             :   // If we're vertically flipping the output, we need to flip the invalid rect. Since we're
      80             :   // dealing with an axis-aligned rect, only the y coordinate needs to change.
      81        1543 :   int32_t invalidY = mFlipVertically
      82        4629 :                    ? InputSize().height - (mRow + 1)
      83        4629 :                    : mRow;
      84        1542 :   mInvalidRect.UnionRect(mInvalidRect,
      85        3085 :                          IntRect(0, invalidY, InputSize().width, 1));
      86             : 
      87        1542 :   mRow = min(uint32_t(InputSize().height), mRow + 1);
      88             : 
      89        3084 :   return mRow < uint32_t(InputSize().height) ? GetRowPointer()
      90        1542 :                                              : nullptr;
      91             : }
      92             : 
      93             : nsresult
      94          48 : SurfaceSink::Configure(const SurfaceConfig& aConfig)
      95             : {
      96             :   // For non-paletted surfaces, the surface size is just the output size.
      97          48 :   IntSize surfaceSize = aConfig.mOutputSize;
      98             : 
      99             :   // Non-paletted surfaces should not have frame rects, so we just pass
     100             :   // AllocateFrame() a frame rect which covers the entire surface.
     101          48 :   IntRect frameRect(0, 0, surfaceSize.width, surfaceSize.height);
     102             : 
     103             :   // Allocate the frame.
     104             :   // XXX(seth): Once every Decoder subclass uses SurfacePipe, we probably want
     105             :   // to allocate the frame directly here and get rid of Decoder::AllocateFrame
     106             :   // altogether.
     107          48 :   nsresult rv = aConfig.mDecoder->AllocateFrame(aConfig.mFrameNum,
     108             :                                                 surfaceSize,
     109             :                                                 frameRect,
     110          96 :                                                 aConfig.mFormat);
     111          48 :   if (NS_FAILED(rv)) {
     112           0 :     return rv;
     113             :   }
     114             : 
     115          48 :   mImageData = aConfig.mDecoder->mImageData;
     116          48 :   mImageDataLength = aConfig.mDecoder->mImageDataLength;
     117          48 :   mFlipVertically = aConfig.mFlipVertically;
     118             : 
     119          48 :   MOZ_ASSERT(mImageData);
     120          48 :   MOZ_ASSERT(mImageDataLength ==
     121             :                uint32_t(surfaceSize.width * surfaceSize.height * sizeof(uint32_t)));
     122             : 
     123          48 :   ConfigureFilter(surfaceSize, sizeof(uint32_t));
     124          48 :   return NS_OK;
     125             : }
     126             : 
     127             : uint8_t*
     128        1542 : SurfaceSink::GetRowPointer() const
     129             : {
     130             :   // If we're flipping vertically, reverse the order in which we traverse the
     131             :   // rows.
     132        1542 :   uint32_t row = mFlipVertically
     133        3084 :                ? InputSize().height - (mRow + 1)
     134        3084 :                : mRow;
     135             : 
     136        1542 :   uint8_t* rowPtr = mImageData + row * InputSize().width * sizeof(uint32_t);
     137             : 
     138        1542 :   MOZ_ASSERT(rowPtr >= mImageData);
     139        1542 :   MOZ_ASSERT(rowPtr < mImageData + mImageDataLength);
     140        1542 :   MOZ_ASSERT(rowPtr + InputSize().width * sizeof(uint32_t) <=
     141             :                mImageData + mImageDataLength);
     142             : 
     143        1542 :   return rowPtr;
     144             : }
     145             : 
     146             : 
     147             : nsresult
     148           0 : PalettedSurfaceSink::Configure(const PalettedSurfaceConfig& aConfig)
     149             : {
     150           0 :   MOZ_ASSERT(aConfig.mFormat == SurfaceFormat::B8G8R8A8);
     151             : 
     152             :   // For paletted surfaces, the surface size is the size of the frame rect.
     153           0 :   IntSize surfaceSize = aConfig.mFrameRect.Size();
     154             : 
     155             :   // Allocate the frame.
     156             :   // XXX(seth): Once every Decoder subclass uses SurfacePipe, we probably want
     157             :   // to allocate the frame directly here and get rid of Decoder::AllocateFrame
     158             :   // altogether.
     159           0 :   nsresult rv = aConfig.mDecoder->AllocateFrame(aConfig.mFrameNum,
     160             :                                                 aConfig.mOutputSize,
     161             :                                                 aConfig.mFrameRect,
     162           0 :                                                 aConfig.mFormat,
     163           0 :                                                 aConfig.mPaletteDepth);
     164           0 :   if (NS_FAILED(rv)) {
     165           0 :     return rv;
     166             :   }
     167             : 
     168           0 :   mImageData = aConfig.mDecoder->mImageData;
     169           0 :   mImageDataLength = aConfig.mDecoder->mImageDataLength;
     170           0 :   mFlipVertically = aConfig.mFlipVertically;
     171           0 :   mFrameRect = aConfig.mFrameRect;
     172             : 
     173           0 :   MOZ_ASSERT(mImageData);
     174           0 :   MOZ_ASSERT(mImageDataLength ==
     175             :                uint32_t(mFrameRect.width * mFrameRect.height * sizeof(uint8_t)));
     176             : 
     177           0 :   ConfigureFilter(surfaceSize, sizeof(uint8_t));
     178           0 :   return NS_OK;
     179             : }
     180             : 
     181             : uint8_t*
     182           0 : PalettedSurfaceSink::GetRowPointer() const
     183             : {
     184             :   // If we're flipping vertically, reverse the order in which we traverse the
     185             :   // rows.
     186           0 :   uint32_t row = mFlipVertically
     187           0 :                ? InputSize().height - (mRow + 1)
     188           0 :                : mRow;
     189             : 
     190           0 :   uint8_t* rowPtr = mImageData + row * InputSize().width * sizeof(uint8_t);
     191             : 
     192           0 :   MOZ_ASSERT(rowPtr >= mImageData);
     193           0 :   MOZ_ASSERT(rowPtr < mImageData + mImageDataLength);
     194           0 :   MOZ_ASSERT(rowPtr + InputSize().width * sizeof(uint8_t) <=
     195             :                mImageData + mImageDataLength);
     196             : 
     197           0 :   return rowPtr;
     198             : }
     199             : 
     200             : } // namespace image
     201             : } // namespace mozilla

Generated by: LCOV version 1.13