blob: 383bcb4555101afccafc537797837e8b31c42e5b [file] [log] [blame]
/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrPixmap_DEFINED
#define GrPixmap_DEFINED
#include "include/core/SkData.h"
#include "include/core/SkPixmap.h"
#include "src/gpu/GrImageInfo.h"
class GrPixmap {
public:
GrPixmap() = default;
GrPixmap(const GrPixmap&) = default;
GrPixmap(GrPixmap&&) = default;
GrPixmap& operator=(const GrPixmap&) = default;
GrPixmap& operator=(GrPixmap&&) = default;
GrPixmap(GrImageInfo info, void* addr, size_t rowBytes)
: fAddr(addr), fRowBytes(rowBytes), fInfo(std::move(info)) {
if (fRowBytes < info.minRowBytes() || !addr) {
*this = {};
}
}
/* implicit */ GrPixmap(const SkPixmap& pixmap)
: GrPixmap(pixmap.info(), pixmap.writable_addr(), pixmap.rowBytes()) {}
/**
* Returns a GrPixmap that owns its backing store. Copies of the pixmap will share ownership.
*/
static GrPixmap Allocate(const GrImageInfo& info) {
size_t rb = info.minRowBytes();
size_t size = info.height()*rb;
if (!size) {
return {};
}
return GrPixmap(info, SkData::MakeUninitialized(size), rb);
}
const GrImageInfo& info() const { return fInfo; }
const GrColorInfo& colorInfo() const { return fInfo.colorInfo(); }
void* addr() const { return fAddr; }
size_t rowBytes() const { return fRowBytes; }
bool hasPixels() const { return SkToBool(fAddr); }
bool ownsPixels() const { return SkToBool(fPixelStorage); }
sk_sp<SkData> pixelStorage() const { return fPixelStorage; }
int width() const { return fInfo.width(); }
int height() const { return fInfo.height(); }
SkISize dimensions() const { return fInfo.dimensions(); }
GrColorType colorType() const { return fInfo.colorType(); }
SkAlphaType alphaType() const { return fInfo.alphaType(); }
/**
* Map this pixmap to a rect in a surface of indicated dimensions at offset surfacePt. Clip the
* logical rectangle to the bounds of the surface. If the rect does not intersect the surface
* bounds or is empty then return a default GrPixmap. Otherwise, surfacePt is updated to refer
* to the upper left of the clipped rectangle. The returned pixmap will refer to the portion
* of the original pixmap inside the surface bounds.
*/
GrPixmap clip(SkISize surfaceDims, SkIPoint* surfacePt) {
auto bounds = SkIRect::MakeSize(surfaceDims);
auto rect = SkIRect::MakePtSize(*surfacePt, this->dimensions());
if (!rect.intersect(bounds)) {
return {};
}
void* addr = static_cast<char*>(fAddr) + (rect.fTop - surfacePt->fY)*fRowBytes +
(rect.fLeft - surfacePt->fX)*fInfo.bpp();
surfacePt->fX = rect.fLeft;
surfacePt->fY = rect.fTop;
return {this->info().makeDimensions(rect.size()), addr, fRowBytes};
}
private:
GrPixmap(GrImageInfo info, sk_sp<SkData> storage, size_t rowBytes)
: GrPixmap(std::move(info), storage->writable_data(), rowBytes) {
fPixelStorage = std::move(storage);
}
void* fAddr = nullptr;
size_t fRowBytes = 0;
GrImageInfo fInfo;
sk_sp<SkData> fPixelStorage;
};
#endif