xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrPixmap.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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