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