LCOV - code coverage report
Current view: top level - gfx/2d - SourceSurfaceSkia.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 24 78 30.8 %
Date: 2017-07-14 16:53:18 Functions: 6 11 54.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; 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             : 
       7             : #include "Logging.h"
       8             : #include "SourceSurfaceSkia.h"
       9             : #include "HelpersSkia.h"
      10             : #include "DrawTargetSkia.h"
      11             : #include "DataSurfaceHelpers.h"
      12             : #include "skia/include/core/SkData.h"
      13             : #include "mozilla/CheckedInt.h"
      14             : 
      15             : namespace mozilla {
      16             : namespace gfx {
      17             : 
      18          37 : SourceSurfaceSkia::SourceSurfaceSkia()
      19          37 :   : mDrawTarget(nullptr)
      20             : {
      21          37 : }
      22             : 
      23          54 : SourceSurfaceSkia::~SourceSurfaceSkia()
      24             : {
      25          18 :   if (mDrawTarget) {
      26          18 :     mDrawTarget->SnapshotDestroyed();
      27          18 :     mDrawTarget = nullptr;
      28             :   }
      29          54 : }
      30             : 
      31             : IntSize
      32         146 : SourceSurfaceSkia::GetSize() const
      33             : {
      34         146 :   return mSize;
      35             : }
      36             : 
      37             : SurfaceFormat
      38         145 : SourceSurfaceSkia::GetFormat() const
      39             : {
      40         145 :   return mFormat;
      41             : }
      42             : 
      43             : static sk_sp<SkData>
      44           0 : MakeSkData(void* aData, int32_t aHeight, size_t aStride)
      45             : {
      46           0 :   CheckedInt<size_t> size = aStride;
      47           0 :   size *= aHeight;
      48           0 :   if (size.isValid()) {
      49           0 :     void* mem = sk_malloc_flags(size.value(), 0);
      50           0 :     if (mem) {
      51           0 :       if (aData) {
      52           0 :         memcpy(mem, aData, size.value());
      53             :       }
      54           0 :       return SkData::MakeFromMalloc(mem, size.value());
      55             :     }
      56             :   }
      57           0 :   return nullptr;
      58             : }
      59             : 
      60             : static sk_sp<SkImage>
      61           0 : ReadSkImage(const sk_sp<SkImage>& aImage, const SkImageInfo& aInfo, size_t aStride)
      62             : {
      63           0 :   if (sk_sp<SkData> data = MakeSkData(nullptr, aInfo.height(), aStride)) {
      64           0 :     if (aImage->readPixels(aInfo, data->writable_data(), aStride, 0, 0, SkImage::kDisallow_CachingHint)) {
      65           0 :       return SkImage::MakeRasterData(aInfo, data, aStride);
      66             :     }
      67             :   }
      68           0 :   return nullptr;
      69             : }
      70             : 
      71             : bool
      72           0 : SourceSurfaceSkia::InitFromData(unsigned char* aData,
      73             :                                 const IntSize &aSize,
      74             :                                 int32_t aStride,
      75             :                                 SurfaceFormat aFormat)
      76             : {
      77           0 :   sk_sp<SkData> data = MakeSkData(aData, aSize.height, aStride);
      78           0 :   if (!data) {
      79           0 :     return false;
      80             :   }
      81             : 
      82           0 :   SkImageInfo info = MakeSkiaImageInfo(aSize, aFormat);
      83           0 :   mImage = SkImage::MakeRasterData(info, data, aStride);
      84           0 :   if (!mImage) {
      85           0 :     return false;
      86             :   }
      87             : 
      88           0 :   mSize = aSize;
      89           0 :   mFormat = aFormat;
      90           0 :   mStride = aStride;
      91           0 :   return true;
      92             : }
      93             : 
      94             : bool
      95          37 : SourceSurfaceSkia::InitFromImage(const sk_sp<SkImage>& aImage,
      96             :                                  SurfaceFormat aFormat,
      97             :                                  DrawTargetSkia* aOwner)
      98             : {
      99          37 :   if (!aImage) {
     100           0 :     return false;
     101             :   }
     102             : 
     103          37 :   mSize = IntSize(aImage->width(), aImage->height());
     104             : 
     105             :   // For the raster image case, we want to use the format and stride
     106             :   // information that the underlying raster image is using, which is
     107             :   // reliable.
     108             :   // For the GPU case (for which peekPixels is false), we can't easily
     109             :   // figure this information out. It is better to report the originally
     110             :   // intended format and stride that we will convert to if this GPU
     111             :   // image is ever read back into a raster image.
     112          74 :   SkPixmap pixmap;
     113          37 :   if (aImage->peekPixels(&pixmap)) {
     114          37 :     mFormat =
     115          37 :       aFormat != SurfaceFormat::UNKNOWN ?
     116             :         aFormat :
     117           0 :         SkiaColorTypeToGfxFormat(pixmap.colorType(), pixmap.alphaType());
     118          37 :     mStride = pixmap.rowBytes();
     119           0 :   } else if (aFormat != SurfaceFormat::UNKNOWN) {
     120           0 :     mFormat = aFormat;
     121           0 :     SkImageInfo info = MakeSkiaImageInfo(mSize, mFormat);
     122           0 :     mStride = SkAlign4(info.minRowBytes());
     123             :   } else {
     124           0 :     return false;
     125             :   }
     126             : 
     127          37 :   mImage = aImage;
     128             : 
     129          37 :   if (aOwner) {
     130          37 :     mDrawTarget = aOwner;
     131             :   }
     132             : 
     133          37 :   return true;
     134             : }
     135             : 
     136             : uint8_t*
     137           0 : SourceSurfaceSkia::GetData()
     138             : {
     139           0 :   if (!mImage) {
     140           0 :     return nullptr;
     141             :   }
     142             : #ifdef USE_SKIA_GPU
     143           0 :   if (mImage->isTextureBacked()) {
     144           0 :     if (sk_sp<SkImage> raster = ReadSkImage(mImage, MakeSkiaImageInfo(mSize, mFormat), mStride)) {
     145           0 :       mImage = raster;
     146             :     } else {
     147           0 :       gfxCriticalError() << "Failed making Skia raster image for GPU surface";
     148             :     }
     149             :   }
     150             : #endif
     151           0 :   SkPixmap pixmap;
     152           0 :   if (!mImage->peekPixels(&pixmap)) {
     153           0 :     gfxCriticalError() << "Failed accessing pixels for Skia raster image";
     154             :   }
     155           0 :   return reinterpret_cast<uint8_t*>(pixmap.writable_addr());
     156             : }
     157             : 
     158             : void
     159           0 : SourceSurfaceSkia::DrawTargetWillChange()
     160             : {
     161           0 :   if (mDrawTarget) {
     162             :     // Raster snapshots do not use Skia's internal copy-on-write mechanism,
     163             :     // so we need to do an explicit copy here.
     164             :     // GPU snapshots, for which peekPixels is false, will already be dealt
     165             :     // with automatically via the internal copy-on-write mechanism, so we
     166             :     // don't need to do anything for them here.
     167           0 :     SkPixmap pixmap;
     168           0 :     if (mImage->peekPixels(&pixmap)) {
     169           0 :       mImage = ReadSkImage(mImage, pixmap.info(), pixmap.rowBytes());
     170           0 :       if (!mImage) {
     171           0 :         gfxCriticalError() << "Failed copying Skia raster snapshot";
     172             :       }
     173             :     }
     174           0 :     mDrawTarget = nullptr;
     175             :   }
     176           0 : }
     177             : 
     178             : } // namespace gfx
     179             : } // namespace mozilla

Generated by: LCOV version 1.13