1 /* 2 * Copyright 2020 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrPixmap_DEFINED 9 #define GrPixmap_DEFINED 10 11 #include "include/core/SkData.h" 12 #include "include/core/SkPixmap.h" 13 #include "include/core/SkPoint.h" 14 #include "include/core/SkRect.h" 15 #include "include/core/SkRefCnt.h" 16 #include "include/core/SkSize.h" 17 #include "include/private/base/SkTLogic.h" 18 #include "include/private/base/SkTo.h" 19 #include "src/gpu/ganesh/GrImageInfo.h" 20 21 #include <cstddef> 22 #include <utility> 23 24 class GrColorInfo; 25 class SkColorSpace; 26 enum SkAlphaType : int; 27 enum class GrColorType; 28 29 template <typename T, typename DERIVED> class GrPixmapBase { 30 public: info()31 const GrImageInfo& info() const { return fInfo; } colorInfo()32 const GrColorInfo& colorInfo() const { return fInfo.colorInfo(); } 33 addr()34 T* addr() const { return fAddr; } rowBytes()35 size_t rowBytes() const { return fRowBytes; } 36 hasPixels()37 bool hasPixels() const { return SkToBool(fAddr); } ownsPixels()38 bool ownsPixels() const { return SkToBool(fPixelStorage); } pixelStorage()39 sk_sp<SkData> pixelStorage() const { return fPixelStorage; } 40 width()41 int width() const { return fInfo.width(); } height()42 int height() const { return fInfo.height(); } dimensions()43 SkISize dimensions() const { return fInfo.dimensions(); } colorType()44 GrColorType colorType() const { return fInfo.colorType(); } alphaType()45 SkAlphaType alphaType() const { return fInfo.alphaType(); } colorSpace()46 SkColorSpace* colorSpace() const { return fInfo.colorSpace(); } refColorSpace()47 sk_sp<SkColorSpace> refColorSpace() const { return fInfo.refColorSpace(); } 48 49 /** 50 * Map this pixmap to a rect in a surface of indicated dimensions at offset surfacePt. Clip the 51 * logical rectangle to the bounds of the surface. If the rect does not intersect the surface 52 * bounds or is empty then return a default GrPixmap. Otherwise, surfacePt is updated to refer 53 * to the upper left of the clipped rectangle. The returned pixmap will refer to the portion 54 * of the original pixmap inside the surface bounds. 55 */ clip(SkISize surfaceDims,SkIPoint * surfacePt)56 DERIVED clip(SkISize surfaceDims, SkIPoint* surfacePt) { 57 auto bounds = SkIRect::MakeSize(surfaceDims); 58 auto rect = SkIRect::MakePtSize(*surfacePt, this->dimensions()); 59 if (!rect.intersect(bounds)) { 60 return {}; 61 } 62 T* addr = static_cast<sknonstd::copy_const_t<char, T>*>(fAddr) + 63 (rect.fTop - surfacePt->fY) * fRowBytes + 64 (rect.fLeft - surfacePt->fX) * fInfo.bpp(); 65 surfacePt->fX = rect.fLeft; 66 surfacePt->fY = rect.fTop; 67 return DERIVED{this->info().makeDimensions(rect.size()), addr, fRowBytes}; 68 } 69 70 protected: 71 GrPixmapBase() = default; 72 GrPixmapBase(const GrPixmapBase& that) = default; 73 GrPixmapBase(GrPixmapBase&& that) = default; 74 GrPixmapBase& operator=(const GrPixmapBase& that) = default; 75 GrPixmapBase& operator=(GrPixmapBase&& that) = default; 76 GrPixmapBase(GrImageInfo info,T * addr,size_t rowBytes)77 GrPixmapBase(GrImageInfo info, T* addr, size_t rowBytes) 78 : fAddr(addr), fRowBytes(rowBytes), fInfo(std::move(info)) { 79 if (fRowBytes < fInfo.minRowBytes() || !addr) { 80 *this = {}; 81 } 82 } 83 GrPixmapBase(GrImageInfo info,sk_sp<SkData> storage,size_t rowBytes)84 GrPixmapBase(GrImageInfo info, sk_sp<SkData> storage, size_t rowBytes) 85 : GrPixmapBase(std::move(info), const_cast<void*>(storage->data()), rowBytes) { 86 fPixelStorage = std::move(storage); 87 } 88 89 private: 90 T* fAddr = nullptr; 91 size_t fRowBytes = 0; 92 GrImageInfo fInfo; 93 sk_sp<SkData> fPixelStorage; 94 }; 95 96 /** A pixmap with mutable pixels. */ 97 class GrPixmap : public GrPixmapBase<void, GrPixmap> { 98 public: 99 GrPixmap() = default; 100 GrPixmap(const GrPixmap&) = default; 101 GrPixmap(GrPixmap&&) = default; 102 GrPixmap& operator=(const GrPixmap&) = default; 103 GrPixmap& operator=(GrPixmap&&) = default; 104 GrPixmap(GrImageInfo info,void * addr,size_t rowBytes)105 GrPixmap(GrImageInfo info, void* addr, size_t rowBytes) 106 : GrPixmapBase(std::move(info), addr, rowBytes) {} 107 GrPixmap(const SkPixmap & pixmap)108 /* implicit */ GrPixmap(const SkPixmap& pixmap) 109 : GrPixmapBase(pixmap.info(), pixmap.writable_addr(), pixmap.rowBytes()) {} 110 111 /** 112 * Returns a GrPixmap that owns its backing store. Copies of the pixmap (as GrPixmap or 113 * GrCPixmap) will share ownership. 114 */ Allocate(const GrImageInfo & info)115 static GrPixmap Allocate(const GrImageInfo& info) { 116 size_t rb = info.minRowBytes(); 117 size_t size = info.height()*rb; 118 if (!size) { 119 return {}; 120 } 121 return GrPixmap(info, SkData::MakeUninitialized(size), rb); 122 } 123 124 private: GrPixmap(GrImageInfo info,sk_sp<SkData> storage,size_t rowBytes)125 GrPixmap(GrImageInfo info, sk_sp<SkData> storage, size_t rowBytes) 126 : GrPixmapBase(std::move(info), std::move(storage), rowBytes) {} 127 }; 128 129 /** 130 * A pixmap with immutable pixels. Note that this pixmap need not be the unique owner of the pixels 131 * and thus it is context-dependent whether the pixels could be manipulated externally. 132 */ 133 class GrCPixmap : public GrPixmapBase<const void, GrCPixmap> { 134 public: 135 GrCPixmap() = default; 136 GrCPixmap(const GrCPixmap&) = default; 137 GrCPixmap(GrCPixmap&&) = default; 138 GrCPixmap& operator=(const GrCPixmap&) = default; 139 GrCPixmap& operator=(GrCPixmap&&) = default; 140 GrCPixmap(const GrPixmap & pixmap)141 /* implicit*/ GrCPixmap(const GrPixmap& pixmap) { 142 if (auto storage = pixmap.pixelStorage()) { 143 *this = GrCPixmap(pixmap.info(), std::move(storage), pixmap.rowBytes()); 144 } else { 145 *this = GrCPixmap(pixmap.info(), pixmap.addr(), pixmap.rowBytes()); 146 } 147 } 148 GrCPixmap(const SkPixmap & pixmap)149 /* implicit */ GrCPixmap(const SkPixmap& pixmap) 150 : GrPixmapBase(pixmap.info(), pixmap.addr(), pixmap.rowBytes()) {} 151 GrCPixmap(GrImageInfo info,const void * addr,size_t rowBytes)152 GrCPixmap(GrImageInfo info, const void* addr, size_t rowBytes) 153 : GrPixmapBase(std::move(info), addr, rowBytes) {} 154 155 private: GrCPixmap(GrImageInfo info,sk_sp<SkData> storage,size_t rowBytes)156 GrCPixmap(GrImageInfo info, sk_sp<SkData> storage, size_t rowBytes) 157 : GrPixmapBase(std::move(info), std::move(storage), rowBytes) {} 158 }; 159 160 #endif 161