2 * Copyright 2020 Google LLC
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef GrPixmap_DEFINED
9 #define GrPixmap_DEFINED
11 #include "include/core/SkData.h"
12 #include "include/core/SkPixmap.h"
13 #include "src/gpu/ganesh/GrImageInfo.h"
15 template <typename T, typename DERIVED> class GrPixmapBase {
17 const GrImageInfo& info() const { return fInfo; }
18 const GrColorInfo& colorInfo() const { return fInfo.colorInfo(); }
20 T* addr() const { return fAddr; }
21 size_t rowBytes() const { return fRowBytes; }
23 bool hasPixels() const { return SkToBool(fAddr); }
24 bool ownsPixels() const { return SkToBool(fPixelStorage); }
25 sk_sp<SkData> pixelStorage() const { return fPixelStorage; }
27 int width() const { return fInfo.width(); }
28 int height() const { return fInfo.height(); }
29 SkISize dimensions() const { return fInfo.dimensions(); }
30 GrColorType colorType() const { return fInfo.colorType(); }
31 SkAlphaType alphaType() const { return fInfo.alphaType(); }
32 SkColorSpace* colorSpace() const { return fInfo.colorSpace(); }
33 sk_sp<SkColorSpace> refColorSpace() const { return fInfo.refColorSpace(); }
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.
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)) {
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};
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;
63 GrPixmapBase(GrImageInfo info, T* addr, size_t rowBytes)
64 : fAddr(addr), fRowBytes(rowBytes), fInfo(std::move(info)) {
65 if (fRowBytes < fInfo.minRowBytes() || !addr) {
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);
79 sk_sp<SkData> fPixelStorage;
82 /** A pixmap with mutable pixels. */
83 class GrPixmap : public GrPixmapBase<void, GrPixmap> {
86 GrPixmap(const GrPixmap&) = default;
87 GrPixmap(GrPixmap&&) = default;
88 GrPixmap& operator=(const GrPixmap&) = default;
89 GrPixmap& operator=(GrPixmap&&) = default;
91 GrPixmap(GrImageInfo info, void* addr, size_t rowBytes) : GrPixmapBase(info, addr, rowBytes) {}
93 /* implicit */ GrPixmap(const SkPixmap& pixmap)
94 : GrPixmapBase(pixmap.info(), pixmap.writable_addr(), pixmap.rowBytes()) {}
97 * Returns a GrPixmap that owns its backing store. Copies of the pixmap (as GrPixmap or
98 * GrCPixmap) will share ownership.
100 static GrPixmap Allocate(const GrImageInfo& info) {
101 size_t rb = info.minRowBytes();
102 size_t size = info.height()*rb;
106 return GrPixmap(info, SkData::MakeUninitialized(size), rb);
110 GrPixmap(GrImageInfo info, sk_sp<SkData> storage, size_t rowBytes)
111 : GrPixmapBase(std::move(info), std::move(storage), rowBytes) {}
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.
118 class GrCPixmap : public GrPixmapBase<const void, GrCPixmap> {
120 GrCPixmap() = default;
121 GrCPixmap(const GrCPixmap&) = default;
122 GrCPixmap(GrCPixmap&&) = default;
123 GrCPixmap& operator=(const GrCPixmap&) = default;
124 GrCPixmap& operator=(GrCPixmap&&) = default;
126 /* implicit*/ GrCPixmap(const GrPixmap& pixmap) {
127 if (auto storage = pixmap.pixelStorage()) {
128 *this = GrCPixmap(pixmap.info(), std::move(storage), pixmap.rowBytes());
130 *this = GrCPixmap(pixmap.info(), pixmap.addr(), pixmap.rowBytes());
134 /* implicit */ GrCPixmap(const SkPixmap& pixmap)
135 : GrPixmapBase(pixmap.info(), pixmap.addr(), pixmap.rowBytes()) {}
137 GrCPixmap(GrImageInfo info, const void* addr, size_t rowBytes)
138 : GrPixmapBase(info, addr, rowBytes) {}
141 GrCPixmap(GrImageInfo info, sk_sp<SkData> storage, size_t rowBytes)
142 : GrPixmapBase(info, std::move(storage), rowBytes) {}