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