GrSurfaceContext::read/writePixels takes GrPixmap
Change readPixels contract to allow unknown->unknown AT reads, but fail if one side is unknown and the other isn't (and update GPU read pixels test accordingly). Also, ProxyUtils::MakeTextureProxyViewFromData takes GrPixmap. Bug: skia:8862 Change-Id: I771c154833408e666f860413c1a711714696326d Reviewed-on: https://skia-review.googlesource.com/c/skia/+/347196 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
parent
12739dffec
commit
dd4087d1e8
@ -28,6 +28,7 @@
|
||||
#include "include/gpu/GrTypes.h"
|
||||
#include "include/private/SkTArray.h"
|
||||
#include "src/gpu/GrDirectContextPriv.h"
|
||||
#include "src/gpu/GrPixmap.h"
|
||||
#include "src/image/SkImage_Base.h"
|
||||
#include "src/image/SkImage_Gpu.h"
|
||||
#include "tools/ToolUtils.h"
|
||||
@ -133,7 +134,7 @@ static sk_sp<SkImage> make_reference_image(GrDirectContext* context,
|
||||
auto origin = bottomLeftOrigin ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
|
||||
|
||||
auto view = sk_gpu_test::MakeTextureProxyViewFromData(context, GrRenderable::kNo, origin,
|
||||
bm.info(), bm.getPixels(), bm.rowBytes());
|
||||
bm.pixmap());
|
||||
if (!view) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -515,7 +515,11 @@ bool GrConvertPixels(const GrImageInfo& dstInfo, void* dst, size_t dstRB,
|
||||
// We don't expect to have to convert from this format.
|
||||
return false;
|
||||
}
|
||||
if (!srcInfo.isValid() || !dstInfo.isValid()) {
|
||||
if (srcInfo.dimensions().isEmpty() || dstInfo.dimensions().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (srcInfo.colorType() == GrColorType::kUnknown ||
|
||||
dstInfo.colorType() == GrColorType::kUnknown) {
|
||||
return false;
|
||||
}
|
||||
if (!src || !dst) {
|
||||
|
@ -44,6 +44,10 @@ public:
|
||||
return {this->colorType(), at, this->refColorSpace(), this->width(), this->height()};
|
||||
}
|
||||
|
||||
GrImageInfo makeDimensions(SkISize dimensions) const {
|
||||
return {this->colorType(), this->alphaType(), this->refColorSpace(), dimensions};
|
||||
}
|
||||
|
||||
GrImageInfo makeWH(int width, int height) const {
|
||||
return {this->colorType(), this->alphaType(), this->refColorSpace(), width, height};
|
||||
}
|
||||
@ -68,28 +72,6 @@ public:
|
||||
|
||||
size_t minRowBytes() const { return this->bpp() * this->width(); }
|
||||
|
||||
/**
|
||||
* Place this image rect in a surface of dimensions surfaceWidth x surfaceHeight size offset at
|
||||
* surfacePt and then clip the pixel rectangle to the bounds of the surface. If the pixel rect
|
||||
* does not intersect the rectangle or is empty then return false. If clipped, the input
|
||||
* surfacePt, the width/height of this GrImageInfo, and the data pointer will be modified to
|
||||
* reflect the clipped rectangle.
|
||||
*/
|
||||
template <typename T>
|
||||
bool clip(int surfaceWidth, int surfaceHeight, SkIPoint* surfacePt, T** data, size_t rowBytes) {
|
||||
auto bounds = SkIRect::MakeWH(surfaceWidth, surfaceHeight);
|
||||
auto rect = SkIRect::MakeXYWH(surfacePt->fX, surfacePt->fY, this->width(), this->height());
|
||||
if (!rect.intersect(bounds)) {
|
||||
return false;
|
||||
}
|
||||
*data = SkTAddOffset<T>(*data, (rect.fTop - surfacePt->fY) * rowBytes +
|
||||
(rect.fLeft - surfacePt->fX) * this->bpp());
|
||||
surfacePt->fX = rect.fLeft;
|
||||
surfacePt->fY = rect.fTop;
|
||||
fDimensions = rect.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isValid() const { return fColorInfo.isValid() && this->width() > 0 && this->height() > 0; }
|
||||
|
||||
private:
|
||||
|
@ -29,13 +29,49 @@ public:
|
||||
: GrPixmap(pixmap.info(), pixmap.writable_addr(), pixmap.rowBytes()) {}
|
||||
|
||||
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); }
|
||||
|
||||
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};
|
||||
}
|
||||
|
||||
/** Returns a GrPixmap and a unique_ptr that owns the storage backing the pixmap. */
|
||||
static std::tuple<GrPixmap, std::unique_ptr<char[]>> Allocate(const GrImageInfo& info) {
|
||||
size_t rb = info.minRowBytes();
|
||||
size_t size = info.height()*rb;
|
||||
if (!size) {
|
||||
return {};
|
||||
}
|
||||
std::unique_ptr<char[]> storage(new char[size]);
|
||||
return {GrPixmap(info, storage.get(), rb), std::move(storage)};
|
||||
}
|
||||
|
||||
private:
|
||||
void* fAddr = nullptr;
|
||||
|
@ -162,8 +162,12 @@ const GrDrawingManager* GrSurfaceContext::drawingManager() const {
|
||||
GrSingleOwner* GrSurfaceContext::singleOwner() const { return fContext->priv().singleOwner(); }
|
||||
#endif
|
||||
|
||||
bool GrSurfaceContext::readPixels(GrDirectContext* dContext, const GrImageInfo& origDstInfo,
|
||||
void* dst, size_t rowBytes, SkIPoint pt) {
|
||||
static bool alpha_types_compatible(SkAlphaType srcAlphaType, SkAlphaType dstAlphaType) {
|
||||
// If both alpha types are kUnknown things make sense. If not, it's too underspecified.
|
||||
return (srcAlphaType == kUnknown_SkAlphaType) == (dstAlphaType == kUnknown_SkAlphaType);
|
||||
}
|
||||
|
||||
bool GrSurfaceContext::readPixels(GrDirectContext* dContext, GrPixmap dst, SkIPoint pt) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
RETURN_FALSE_IF_ABANDONED
|
||||
SkDEBUGCODE(this->validate();)
|
||||
@ -171,21 +175,15 @@ bool GrSurfaceContext::readPixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
if (!fContext->priv().matches(dContext)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!dst) {
|
||||
dst = dst.clip(this->dimensions(), &pt);
|
||||
if (!dst.hasPixels()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t tightRowBytes = origDstInfo.minRowBytes();
|
||||
if (!rowBytes) {
|
||||
rowBytes = tightRowBytes;
|
||||
} else if (rowBytes < tightRowBytes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!origDstInfo.isValid()) {
|
||||
if (!alpha_types_compatible(this->colorInfo().alphaType(), dst.alphaType())) {
|
||||
return false;
|
||||
}
|
||||
// We allow unknown alpha types but only if both src and dst are unknown. Otherwise, it's too
|
||||
// weird to reason about what should be expected.
|
||||
|
||||
GrSurfaceProxy* srcProxy = this->asSurfaceProxy();
|
||||
|
||||
@ -200,14 +198,8 @@ bool GrSurfaceContext::readPixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
|
||||
GrSurface* srcSurface = srcProxy->peekSurface();
|
||||
|
||||
auto dstInfo = origDstInfo;
|
||||
if (!dstInfo.clip(this->width(), this->height(), &pt, &dst, rowBytes)) {
|
||||
return false;
|
||||
}
|
||||
// Our tight row bytes may have been changed by clipping.
|
||||
tightRowBytes = dstInfo.minRowBytes();
|
||||
|
||||
SkColorSpaceXformSteps::Flags flags = SkColorSpaceXformSteps{this->colorInfo(), dstInfo}.flags;
|
||||
SkColorSpaceXformSteps::Flags flags =
|
||||
SkColorSpaceXformSteps{this->colorInfo(), dst.info()}.flags;
|
||||
bool unpremul = flags.unpremul,
|
||||
needColorConversion = flags.linearize || flags.gamut_transform || flags.encode,
|
||||
premul = flags.premul;
|
||||
@ -223,8 +215,8 @@ bool GrSurfaceContext::readPixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
GrRenderable::kYes);
|
||||
GrColorType srcColorType = this->colorInfo().colorType();
|
||||
bool canvas2DFastPath = unpremul && !needColorConversion &&
|
||||
(GrColorType::kRGBA_8888 == dstInfo.colorType() ||
|
||||
GrColorType::kBGRA_8888 == dstInfo.colorType()) &&
|
||||
(GrColorType::kRGBA_8888 == dst.colorType() ||
|
||||
GrColorType::kBGRA_8888 == dst.colorType()) &&
|
||||
SkToBool(srcProxy->asTextureProxy()) &&
|
||||
(srcColorType == GrColorType::kRGBA_8888 ||
|
||||
srcColorType == GrColorType::kBGRA_8888) &&
|
||||
@ -242,12 +234,12 @@ bool GrSurfaceContext::readPixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
GrColorType colorType = (canvas2DFastPath || srcIsCompressed)
|
||||
? GrColorType::kRGBA_8888
|
||||
: this->colorInfo().colorType();
|
||||
SkAlphaType alphaType = canvas2DFastPath ? dstInfo.alphaType()
|
||||
SkAlphaType alphaType = canvas2DFastPath ? dst.alphaType()
|
||||
: this->colorInfo().alphaType();
|
||||
GrImageInfo tempInfo(colorType,
|
||||
alphaType,
|
||||
this->colorInfo().refColorSpace(),
|
||||
dstInfo.dimensions());
|
||||
dst.dimensions());
|
||||
auto sfc = GrSurfaceFillContext::Make(dContext, tempInfo, SkBackingFit::kApprox);
|
||||
if (!sfc) {
|
||||
return false;
|
||||
@ -257,9 +249,11 @@ bool GrSurfaceContext::readPixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
if (canvas2DFastPath) {
|
||||
fp = dContext->priv().createPMToUPMEffect(GrTextureEffect::Make(
|
||||
this->readSurfaceView(), this->colorInfo().alphaType()));
|
||||
if (dstInfo.colorType() == GrColorType::kBGRA_8888) {
|
||||
if (dst.colorType() == GrColorType::kBGRA_8888) {
|
||||
fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), GrSwizzle::BGRA());
|
||||
dstInfo = dstInfo.makeColorType(GrColorType::kRGBA_8888);
|
||||
dst = GrPixmap(dst.info().makeColorType(GrColorType::kRGBA_8888),
|
||||
dst.addr(),
|
||||
dst.rowBytes());
|
||||
}
|
||||
} else {
|
||||
fp = GrTextureEffect::Make(this->readSurfaceView(), this->colorInfo().alphaType());
|
||||
@ -267,8 +261,8 @@ bool GrSurfaceContext::readPixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
if (!fp) {
|
||||
return false;
|
||||
}
|
||||
sfc->fillRectToRectWithFP(SkIRect::MakePtSize(pt, dstInfo.dimensions()),
|
||||
SkIRect::MakeSize(dstInfo.dimensions()),
|
||||
sfc->fillRectToRectWithFP(SkIRect::MakePtSize(pt, dst.dimensions()),
|
||||
SkIRect::MakeSize(dst.dimensions()),
|
||||
std::move(fp));
|
||||
pt = {0, 0};
|
||||
tempCtx = std::move(sfc);
|
||||
@ -283,7 +277,7 @@ bool GrSurfaceContext::readPixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
copy = GrSurfaceProxy::Copy(fContext, srcProxy, this->origin(), kMipMapped, kFit,
|
||||
kBudgeted);
|
||||
} else {
|
||||
auto srcRect = SkIRect::MakeXYWH(pt.fX, pt.fY, dstInfo.width(), dstInfo.height());
|
||||
auto srcRect = SkIRect::MakePtSize(pt, dst.dimensions());
|
||||
copy = GrSurfaceProxy::Copy(fContext, srcProxy, this->origin(), kMipMapped, srcRect,
|
||||
kFit, kBudgeted, restrictions.fRectsMustMatch);
|
||||
pt = {0, 0};
|
||||
@ -295,52 +289,55 @@ bool GrSurfaceContext::readPixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
tempCtx = GrSurfaceContext::Make(dContext, std::move(view), this->colorInfo());
|
||||
SkASSERT(tempCtx);
|
||||
}
|
||||
return tempCtx->readPixels(dContext, dstInfo, dst, rowBytes, pt);
|
||||
return tempCtx->readPixels(dContext, dst, pt);
|
||||
}
|
||||
|
||||
bool flip = this->origin() == kBottomLeft_GrSurfaceOrigin;
|
||||
|
||||
auto supportedRead = caps->supportedReadPixelsColorType(
|
||||
this->colorInfo().colorType(), srcProxy->backendFormat(), dstInfo.colorType());
|
||||
this->colorInfo().colorType(), srcProxy->backendFormat(), dst.colorType());
|
||||
|
||||
bool makeTight = !caps->readPixelsRowBytesSupport() && tightRowBytes != rowBytes;
|
||||
bool makeTight =
|
||||
!caps->readPixelsRowBytesSupport() && dst.rowBytes() != dst.info().minRowBytes();
|
||||
|
||||
bool convert = unpremul || premul || needColorConversion || flip || makeTight ||
|
||||
(dstInfo.colorType() != supportedRead.fColorType);
|
||||
(dst.colorType() != supportedRead.fColorType);
|
||||
|
||||
std::unique_ptr<char[]> tmpPixels;
|
||||
GrImageInfo tmpInfo;
|
||||
void* readDst = dst;
|
||||
size_t readRB = rowBytes;
|
||||
GrPixmap tmp;
|
||||
void* readDst = dst.addr();
|
||||
size_t readRB = dst.rowBytes();
|
||||
if (convert) {
|
||||
tmpInfo = {supportedRead.fColorType, this->colorInfo().alphaType(),
|
||||
this->colorInfo().refColorSpace(), dstInfo.width(), dstInfo.height()};
|
||||
GrImageInfo tmpInfo(supportedRead.fColorType,
|
||||
this->colorInfo().alphaType(),
|
||||
this->colorInfo().refColorSpace(),
|
||||
dst.dimensions());
|
||||
size_t tmpRB = tmpInfo.minRowBytes();
|
||||
size_t size = tmpRB * tmpInfo.height();
|
||||
// Chrome MSAN bots require the data to be initialized (hence the ()).
|
||||
tmpPixels = std::make_unique<char[]>(size);
|
||||
tmp = {tmpInfo, tmpPixels.get(), tmpRB};
|
||||
|
||||
readDst = tmpPixels.get();
|
||||
readRB = tmpRB;
|
||||
pt.fY = flip ? srcSurface->height() - pt.fY - dstInfo.height() : pt.fY;
|
||||
pt.fY = flip ? srcSurface->height() - pt.fY - dst.height() : pt.fY;
|
||||
}
|
||||
|
||||
dContext->priv().flushSurface(srcProxy);
|
||||
dContext->submit();
|
||||
if (!dContext->priv().getGpu()->readPixels(srcSurface, pt.fX, pt.fY, dstInfo.width(),
|
||||
dstInfo.height(), this->colorInfo().colorType(),
|
||||
if (!dContext->priv().getGpu()->readPixels(srcSurface, pt.fX, pt.fY, dst.width(), dst.height(),
|
||||
this->colorInfo().colorType(),
|
||||
supportedRead.fColorType, readDst, readRB)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (convert) {
|
||||
return GrConvertPixels(dstInfo, dst, rowBytes, tmpInfo, readDst, readRB, flip);
|
||||
if (tmp.hasPixels()) {
|
||||
return GrConvertPixels(dst, tmp, flip);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrSurfaceContext::writePixels(GrDirectContext* dContext, const GrImageInfo& origSrcInfo,
|
||||
const void* src, size_t rowBytes, SkIPoint pt) {
|
||||
bool GrSurfaceContext::writePixels(GrDirectContext* dContext, GrPixmap src, SkIPoint pt) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
RETURN_FALSE_IF_ABANDONED
|
||||
SkDEBUGCODE(this->validate();)
|
||||
@ -354,18 +351,11 @@ bool GrSurfaceContext::writePixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!src) {
|
||||
src = src.clip(this->dimensions(), &pt);
|
||||
if (!src.hasPixels()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t tightRowBytes = origSrcInfo.minRowBytes();
|
||||
if (!rowBytes) {
|
||||
rowBytes = tightRowBytes;
|
||||
} else if (rowBytes < tightRowBytes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!origSrcInfo.isValid()) {
|
||||
if (!alpha_types_compatible(src.alphaType(), this->colorInfo().alphaType())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -381,14 +371,8 @@ bool GrSurfaceContext::writePixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
|
||||
GrSurface* dstSurface = dstProxy->peekSurface();
|
||||
|
||||
auto srcInfo = origSrcInfo;
|
||||
if (!srcInfo.clip(this->width(), this->height(), &pt, &src, rowBytes)) {
|
||||
return false;
|
||||
}
|
||||
// Our tight row bytes may have been changed by clipping.
|
||||
tightRowBytes = srcInfo.minRowBytes();
|
||||
|
||||
SkColorSpaceXformSteps::Flags flags = SkColorSpaceXformSteps{srcInfo, this->colorInfo()}.flags;
|
||||
SkColorSpaceXformSteps::Flags flags =
|
||||
SkColorSpaceXformSteps{src.info(), this->colorInfo()}.flags;
|
||||
bool unpremul = flags.unpremul,
|
||||
needColorConversion = flags.linearize || flags.gamut_transform || flags.encode,
|
||||
premul = flags.premul;
|
||||
@ -402,8 +386,8 @@ bool GrSurfaceContext::writePixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
// For canvas2D putImageData performance we have a special code path for unpremul RGBA_8888 srcs
|
||||
// that are premultiplied on the GPU. This is kept as narrow as possible for now.
|
||||
bool canvas2DFastPath = !caps->avoidWritePixelsFastPath() && premul && !needColorConversion &&
|
||||
(srcInfo.colorType() == GrColorType::kRGBA_8888 ||
|
||||
srcInfo.colorType() == GrColorType::kBGRA_8888) &&
|
||||
(src.colorType() == GrColorType::kRGBA_8888 ||
|
||||
src.colorType() == GrColorType::kBGRA_8888) &&
|
||||
this->asFillContext() &&
|
||||
(dstColorType == GrColorType::kRGBA_8888 ||
|
||||
dstColorType == GrColorType::kBGRA_8888) &&
|
||||
@ -436,7 +420,7 @@ bool GrSurfaceContext::writePixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
GrSurfaceOrigin tempOrigin =
|
||||
this->asFillContext() ? kTopLeft_GrSurfaceOrigin : this->origin();
|
||||
auto tempProxy = dContext->priv().proxyProvider()->createProxy(
|
||||
format, srcInfo.dimensions(), GrRenderable::kNo, 1, GrMipmapped::kNo,
|
||||
format, src.dimensions(), GrRenderable::kNo, 1, GrMipmapped::kNo,
|
||||
SkBackingFit::kApprox, SkBudgeted::kYes, GrProtected::kNo);
|
||||
if (!tempProxy) {
|
||||
return false;
|
||||
@ -448,10 +432,11 @@ bool GrSurfaceContext::writePixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
// When the data is really BGRA the write will cause the R and B channels to be swapped in
|
||||
// the intermediate surface which gets corrected by a swizzle effect when drawing to the
|
||||
// dst.
|
||||
GrColorType origSrcColorType = src.colorType();
|
||||
if (canvas2DFastPath) {
|
||||
srcInfo = srcInfo.makeColorType(GrColorType::kRGBA_8888);
|
||||
src = {src.info().makeColorType(GrColorType::kRGBA_8888), src.addr(), src.rowBytes()};
|
||||
}
|
||||
if (!tempCtx.writePixels(dContext, srcInfo, src, rowBytes, {0, 0})) {
|
||||
if (!tempCtx.writePixels(dContext, src, {0, 0})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -461,7 +446,7 @@ bool GrSurfaceContext::writePixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
fp = dContext->priv().createUPMToPMEffect(
|
||||
GrTextureEffect::Make(std::move(tempView), tempColorInfo.alphaType()));
|
||||
// Important: check the original src color type here!
|
||||
if (origSrcInfo.colorType() == GrColorType::kBGRA_8888) {
|
||||
if (origSrcColorType == GrColorType::kBGRA_8888) {
|
||||
fp = GrFragmentProcessor::SwizzleOutput(std::move(fp), GrSwizzle::BGRA());
|
||||
}
|
||||
} else {
|
||||
@ -470,12 +455,11 @@ bool GrSurfaceContext::writePixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
if (!fp) {
|
||||
return false;
|
||||
}
|
||||
this->asFillContext()->fillRectToRectWithFP(
|
||||
SkIRect::MakeSize(srcInfo.dimensions()),
|
||||
SkIRect::MakePtSize(pt, srcInfo.dimensions()),
|
||||
this->asFillContext()->fillRectToRectWithFP(SkIRect::MakeSize(src.dimensions()),
|
||||
SkIRect::MakePtSize(pt, src.dimensions()),
|
||||
std::move(fp));
|
||||
} else {
|
||||
SkIRect srcRect = SkIRect::MakeWH(srcInfo.width(), srcInfo.height());
|
||||
SkIRect srcRect = SkIRect::MakeSize(src.dimensions());
|
||||
SkIPoint dstPoint = SkIPoint::Make(pt.fX, pt.fY);
|
||||
if (!this->copy(tempProxy.get(), srcRect, dstPoint)) {
|
||||
return false;
|
||||
@ -487,25 +471,26 @@ bool GrSurfaceContext::writePixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
GrColorType allowedColorType =
|
||||
caps->supportedWritePixelsColorType(this->colorInfo().colorType(),
|
||||
dstProxy->backendFormat(),
|
||||
srcInfo.colorType()).fColorType;
|
||||
src.colorType()).fColorType;
|
||||
bool flip = this->origin() == kBottomLeft_GrSurfaceOrigin;
|
||||
bool makeTight = !caps->writePixelsRowBytesSupport() && rowBytes != tightRowBytes;
|
||||
bool makeTight = !caps->writePixelsRowBytesSupport() &&
|
||||
src.rowBytes() != src.info().minRowBytes();
|
||||
bool convert = premul || unpremul || needColorConversion || makeTight ||
|
||||
(srcInfo.colorType() != allowedColorType) || flip;
|
||||
(src.colorType() != allowedColorType) || flip;
|
||||
|
||||
std::unique_ptr<char[]> tmpPixels;
|
||||
GrColorType srcColorType = srcInfo.colorType();
|
||||
if (convert) {
|
||||
GrImageInfo tmpInfo(allowedColorType, this->colorInfo().alphaType(),
|
||||
this->colorInfo().refColorSpace(), srcInfo.width(), srcInfo.height());
|
||||
GrImageInfo tmpInfo(allowedColorType,
|
||||
this->colorInfo().alphaType(),
|
||||
this->colorInfo().refColorSpace(),
|
||||
src.dimensions());
|
||||
auto tmpRB = tmpInfo.minRowBytes();
|
||||
tmpPixels.reset(new char[tmpRB * tmpInfo.height()]);
|
||||
GrPixmap tmp(tmpInfo, tmpPixels.get(), tmpRB);
|
||||
|
||||
GrConvertPixels(tmpInfo, tmpPixels.get(), tmpRB, srcInfo, src, rowBytes, flip);
|
||||
SkAssertResult(GrConvertPixels(tmp, src, flip));
|
||||
|
||||
srcColorType = tmpInfo.colorType();
|
||||
rowBytes = tmpRB;
|
||||
src = tmpPixels.get();
|
||||
src = tmp;
|
||||
pt.fY = flip ? dstSurface->height() - pt.fY - tmpInfo.height() : pt.fY;
|
||||
}
|
||||
|
||||
@ -516,9 +501,9 @@ bool GrSurfaceContext::writePixels(GrDirectContext* dContext, const GrImageInfo&
|
||||
// TODO: should this policy decision just be moved into the drawing manager?
|
||||
dContext->priv().flushSurface(caps->preferVRAMUseOverFlushes() ? dstProxy : nullptr);
|
||||
|
||||
return dContext->priv().getGpu()->writePixels(dstSurface, pt.fX, pt.fY, srcInfo.width(),
|
||||
srcInfo.height(), this->colorInfo().colorType(),
|
||||
srcColorType, src, rowBytes);
|
||||
return dContext->priv().getGpu()->writePixels(dstSurface, pt.fX, pt.fY, src.width(),
|
||||
src.height(), this->colorInfo().colorType(),
|
||||
src.colorType(), src.addr(), src.rowBytes());
|
||||
}
|
||||
|
||||
void GrSurfaceContext::asyncRescaleAndReadPixels(GrDirectContext* dContext,
|
||||
@ -732,7 +717,7 @@ void GrSurfaceContext::asyncReadPixels(GrDirectContext* dContext,
|
||||
result->addCpuPlane(std::move(data), pm.rowBytes());
|
||||
|
||||
SkIPoint pt{rect.fLeft, rect.fTop};
|
||||
if (!this->readPixels(dContext, ii, pm.writable_addr(), pm.rowBytes(), pt)) {
|
||||
if (!this->readPixels(dContext, pm, pt)) {
|
||||
callback(callbackContext, nullptr);
|
||||
return;
|
||||
}
|
||||
@ -976,21 +961,19 @@ void GrSurfaceContext::asyncRescaleAndReadPixelsYUV420(GrDirectContext* dContext
|
||||
if (doSynchronousRead) {
|
||||
GrImageInfo yInfo(GrColorType::kAlpha_8, kPremul_SkAlphaType, nullptr, dstSize);
|
||||
GrImageInfo uvInfo = yInfo.makeWH(halfW, halfH);
|
||||
size_t yRB = yInfo.minRowBytes();
|
||||
size_t uvRB = uvInfo.minRowBytes();
|
||||
std::unique_ptr<char[]> y(new char[yRB * yInfo.height()]);
|
||||
std::unique_ptr<char[]> u(new char[uvRB*uvInfo.height()]);
|
||||
std::unique_ptr<char[]> v(new char[uvRB*uvInfo.height()]);
|
||||
if (!yRTC->readPixels(dContext, yInfo, y.get(), yRB, {0, 0}) ||
|
||||
!uRTC->readPixels(dContext, uvInfo, u.get(), uvRB, {0, 0}) ||
|
||||
!vRTC->readPixels(dContext, uvInfo, v.get(), uvRB, {0, 0})) {
|
||||
auto [yPmp, yStorage] = GrPixmap::Allocate(yInfo);
|
||||
auto [uPmp, uStorage] = GrPixmap::Allocate(uvInfo);
|
||||
auto [vPmp, vStorage] = GrPixmap::Allocate(uvInfo);
|
||||
if (!yRTC->readPixels(dContext, yPmp, {0, 0}) ||
|
||||
!uRTC->readPixels(dContext, uPmp, {0, 0}) ||
|
||||
!vRTC->readPixels(dContext, vPmp, {0, 0})) {
|
||||
callback(callbackContext, nullptr);
|
||||
return;
|
||||
}
|
||||
auto result = std::make_unique<AsyncReadResult>(dContext->priv().contextID());
|
||||
result->addCpuPlane(std::move(y), yRB );
|
||||
result->addCpuPlane(std::move(u), uvRB);
|
||||
result->addCpuPlane(std::move(v), uvRB);
|
||||
result->addCpuPlane(std::move(yStorage), yPmp.rowBytes());
|
||||
result->addCpuPlane(std::move(uStorage), uPmp.rowBytes());
|
||||
result->addCpuPlane(std::move(vStorage), vPmp.rowBytes());
|
||||
callback(callbackContext, std::move(result));
|
||||
return;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "src/gpu/GrColorInfo.h"
|
||||
#include "src/gpu/GrDataUtils.h"
|
||||
#include "src/gpu/GrImageInfo.h"
|
||||
#include "src/gpu/GrPixmap.h"
|
||||
#include "src/gpu/GrSurfaceProxy.h"
|
||||
#include "src/gpu/GrSurfaceProxyView.h"
|
||||
|
||||
@ -92,19 +93,13 @@ public:
|
||||
const GrCaps* caps() const;
|
||||
|
||||
/**
|
||||
* Reads a rectangle of pixels from the render target context.
|
||||
* Reads a rectangle of pixels from the surface context.
|
||||
* @param dContext The direct context to use
|
||||
* @param dstInfo image info for the destination
|
||||
* @param dst destination pixels for the read
|
||||
* @param rowBytes bytes in a row of 'dst'
|
||||
* @param srcPt offset w/in the surface context from which to read
|
||||
* is a GrDirectContext and fail otherwise.
|
||||
*/
|
||||
bool readPixels(GrDirectContext* dContext,
|
||||
const GrImageInfo& dstInfo,
|
||||
void* dst,
|
||||
size_t rowBytes,
|
||||
SkIPoint srcPt);
|
||||
bool readPixels(GrDirectContext* dContext, GrPixmap dst, SkIPoint srcPt);
|
||||
|
||||
using ReadPixelsCallback = SkImage::ReadPixelsCallback;
|
||||
using ReadPixelsContext = SkImage::ReadPixelsContext;
|
||||
@ -134,16 +129,10 @@ public:
|
||||
* Writes a rectangle of pixels [srcInfo, srcBuffer, srcRowbytes] into the
|
||||
* surfaceDrawContext at the specified position.
|
||||
* @param dContext The direct context to use
|
||||
* @param srcInfo image info for the source pixels
|
||||
* @param src source for the write
|
||||
* @param rowBytes bytes in a row of 'src'
|
||||
* @param dstPt offset w/in the surface context at which to write
|
||||
*/
|
||||
bool writePixels(GrDirectContext* dContext,
|
||||
const GrImageInfo& srcInfo,
|
||||
const void* src,
|
||||
size_t rowBytes,
|
||||
SkIPoint dstPt);
|
||||
bool writePixels(GrDirectContext* dContext, GrPixmap src, SkIPoint dstPt);
|
||||
|
||||
GrSurfaceProxy* asSurfaceProxy() { return fReadView.proxy(); }
|
||||
const GrSurfaceProxy* asSurfaceProxy() const { return fReadView.proxy(); }
|
||||
@ -178,7 +167,7 @@ public:
|
||||
SkFilterQuality);
|
||||
|
||||
/**
|
||||
* Like the above but allows the caller ot specify a destination render target context and
|
||||
* Like the above but allows the caller ot specify a destination draw context and
|
||||
* rect within that context. The dst rect must be contained by the dst or this will fail.
|
||||
*/
|
||||
bool rescaleInto(GrSurfaceDrawContext* dst,
|
||||
|
@ -174,8 +174,7 @@ bool SkGpuDevice::onReadPixels(const SkPixmap& pm, int x, int y) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return fSurfaceDrawContext->readPixels(dContext, pm.info(), pm.writable_addr(), pm.rowBytes(),
|
||||
{x, y});
|
||||
return fSurfaceDrawContext->readPixels(dContext, pm, {x, y});
|
||||
}
|
||||
|
||||
bool SkGpuDevice::onWritePixels(const SkPixmap& pm, int x, int y) {
|
||||
@ -187,7 +186,7 @@ bool SkGpuDevice::onWritePixels(const SkPixmap& pm, int x, int y) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return fSurfaceDrawContext->writePixels(dContext, pm.info(), pm.addr(), pm.rowBytes(), {x, y});
|
||||
return fSurfaceDrawContext->writePixels(dContext, pm, {x, y});
|
||||
}
|
||||
|
||||
bool SkGpuDevice::onAccessPixels(SkPixmap* pmap) {
|
||||
|
@ -24,8 +24,6 @@ in fragmentProcessor inputFP;
|
||||
static constexpr int kSize = 256;
|
||||
SkAutoTMalloc<uint32_t> data(kSize * kSize * 3);
|
||||
uint32_t* srcData = data.get();
|
||||
uint32_t* firstRead = data.get() + kSize * kSize;
|
||||
uint32_t* secondRead = data.get() + 2 * kSize * kSize;
|
||||
|
||||
// Fill with every possible premultiplied A, color channel value. There will be 256-y
|
||||
// duplicate values in row y. We set r, g, and b to the same value since they are handled
|
||||
@ -39,8 +37,6 @@ in fragmentProcessor inputFP;
|
||||
color[0] = std::min(x, y);
|
||||
}
|
||||
}
|
||||
std::fill_n( firstRead, kSize * kSize, 0);
|
||||
std::fill_n(secondRead, kSize * kSize, 0);
|
||||
|
||||
const SkImageInfo pmII =
|
||||
SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
|
||||
@ -65,6 +61,14 @@ in fragmentProcessor inputFP;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t* firstRead = data.get() + kSize*kSize;
|
||||
uint32_t* secondRead = data.get() + 2*kSize*kSize;
|
||||
std::fill_n( firstRead, kSize*kSize, 0);
|
||||
std::fill_n(secondRead, kSize*kSize, 0);
|
||||
|
||||
GrPixmap firstReadPM( upmII, firstRead, kSize*sizeof(uint32_t));
|
||||
GrPixmap secondReadPM(upmII, secondRead, kSize*sizeof(uint32_t));
|
||||
|
||||
// We do a PM->UPM draw from dataTex to readTex and read the data. Then we do a UPM->PM draw
|
||||
// from readTex to tempTex followed by a PM->UPM draw to readTex and finally read the data.
|
||||
// We then verify that two reads produced the same values.
|
||||
@ -73,7 +77,7 @@ in fragmentProcessor inputFP;
|
||||
bitmap.alphaType()),
|
||||
PMConversion::kToUnpremul);
|
||||
readSFC->fillRectWithFP(SkIRect::MakeWH(kSize, kSize), std::move(fp1));
|
||||
if (!readSFC->readPixels(dContext, upmII, firstRead, 0, {0, 0})) {
|
||||
if (!readSFC->readPixels(dContext, firstReadPM, {0, 0})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -89,7 +93,7 @@ in fragmentProcessor inputFP;
|
||||
PMConversion::kToUnpremul);
|
||||
readSFC->fillRectWithFP(SkIRect::MakeWH(kSize, kSize), std::move(fp3));
|
||||
|
||||
if (!readSFC->readPixels(dContext, upmII, secondRead, 0, {0, 0})) {
|
||||
if (!readSFC->readPixels(dContext, secondReadPM, {0, 0})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -89,8 +89,6 @@ bool GrConfigConversionEffect::TestForPreservingPMConversions(GrDirectContext* d
|
||||
static constexpr int kSize = 256;
|
||||
SkAutoTMalloc<uint32_t> data(kSize * kSize * 3);
|
||||
uint32_t* srcData = data.get();
|
||||
uint32_t* firstRead = data.get() + kSize * kSize;
|
||||
uint32_t* secondRead = data.get() + 2 * kSize * kSize;
|
||||
|
||||
// Fill with every possible premultiplied A, color channel value. There will be 256-y
|
||||
// duplicate values in row y. We set r, g, and b to the same value since they are handled
|
||||
@ -104,8 +102,6 @@ bool GrConfigConversionEffect::TestForPreservingPMConversions(GrDirectContext* d
|
||||
color[0] = std::min(x, y);
|
||||
}
|
||||
}
|
||||
std::fill_n(firstRead, kSize * kSize, 0);
|
||||
std::fill_n(secondRead, kSize * kSize, 0);
|
||||
|
||||
const SkImageInfo pmII =
|
||||
SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
|
||||
@ -130,6 +126,14 @@ bool GrConfigConversionEffect::TestForPreservingPMConversions(GrDirectContext* d
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t* firstRead = data.get() + kSize * kSize;
|
||||
uint32_t* secondRead = data.get() + 2 * kSize * kSize;
|
||||
std::fill_n(firstRead, kSize * kSize, 0);
|
||||
std::fill_n(secondRead, kSize * kSize, 0);
|
||||
|
||||
GrPixmap firstReadPM(upmII, firstRead, kSize * sizeof(uint32_t));
|
||||
GrPixmap secondReadPM(upmII, secondRead, kSize * sizeof(uint32_t));
|
||||
|
||||
// We do a PM->UPM draw from dataTex to readTex and read the data. Then we do a UPM->PM draw
|
||||
// from readTex to tempTex followed by a PM->UPM draw to readTex and finally read the data.
|
||||
// We then verify that two reads produced the same values.
|
||||
@ -138,7 +142,7 @@ bool GrConfigConversionEffect::TestForPreservingPMConversions(GrDirectContext* d
|
||||
GrTextureEffect::Make(std::move(dataView), bitmap.alphaType()),
|
||||
PMConversion::kToUnpremul);
|
||||
readSFC->fillRectWithFP(SkIRect::MakeWH(kSize, kSize), std::move(fp1));
|
||||
if (!readSFC->readPixels(dContext, upmII, firstRead, 0, {0, 0})) {
|
||||
if (!readSFC->readPixels(dContext, firstReadPM, {0, 0})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -152,7 +156,7 @@ bool GrConfigConversionEffect::TestForPreservingPMConversions(GrDirectContext* d
|
||||
PMConversion::kToUnpremul);
|
||||
readSFC->fillRectWithFP(SkIRect::MakeWH(kSize, kSize), std::move(fp3));
|
||||
|
||||
if (!readSFC->readPixels(dContext, upmII, secondRead, 0, {0, 0})) {
|
||||
if (!readSFC->readPixels(dContext, secondReadPM, {0, 0})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -241,7 +241,7 @@ static bool save_pixels(GrDirectContext* dContext, GrSurfaceProxyView view, GrCo
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = sContext->readPixels(dContext, ii, bm.getPixels(), bm.rowBytes(), {0, 0});
|
||||
bool result = sContext->readPixels(dContext, bm.pixmap(), {0, 0});
|
||||
if (!result) {
|
||||
SkDebugf("------ failed to read pixels for %s\n", filename);
|
||||
return false;
|
||||
|
@ -554,7 +554,7 @@ sk_sp<SkImage> SkImage::MakeFromAHardwareBufferWithData(GrDirectContext* dContex
|
||||
|
||||
GrSurfaceContext surfaceContext(dContext, std::move(view), image->imageInfo().colorInfo());
|
||||
|
||||
surfaceContext.writePixels(dContext, pixmap.info(), pixmap.addr(), pixmap.rowBytes(), {0, 0});
|
||||
surfaceContext.writePixels(dContext, pixmap, {0, 0});
|
||||
|
||||
GrSurfaceProxy* p[1] = {surfaceContext.asSurfaceProxy()};
|
||||
drawingManager->flush(p, SkSurface::BackendSurfaceAccess::kNoAccess, {}, nullptr);
|
||||
|
@ -126,8 +126,7 @@ bool SkImage_GpuBase::getROPixels(GrDirectContext* dContext,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sContext->readPixels(dContext, pmap.info(), pmap.writable_addr(), pmap.rowBytes(),
|
||||
{0, 0})) {
|
||||
if (!sContext->readPixels(dContext, pmap, {0, 0})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -166,8 +165,8 @@ bool SkImage_GpuBase::onReadPixels(GrDirectContext* dContext,
|
||||
int srcX,
|
||||
int srcY,
|
||||
CachingHint) const {
|
||||
if (!fContext->priv().matches(dContext)
|
||||
|| !SkImageInfoValidConversion(dstInfo, this->imageInfo())) {
|
||||
if (!fContext->priv().matches(dContext) ||
|
||||
!SkImageInfoValidConversion(dstInfo, this->imageInfo())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -182,7 +181,7 @@ bool SkImage_GpuBase::onReadPixels(GrDirectContext* dContext,
|
||||
return false;
|
||||
}
|
||||
|
||||
return sContext->readPixels(dContext, dstInfo, dstPixels, dstRB, {srcX, srcY});
|
||||
return sContext->readPixels(dContext, {dstInfo, dstPixels, dstRB}, {srcX, srcY});
|
||||
}
|
||||
|
||||
GrSurfaceProxyView SkImage_GpuBase::refView(GrRecordingContext* context,
|
||||
|
@ -275,8 +275,7 @@ static void check_base_readbacks(GrDirectContext* dContext,
|
||||
ERRORF(reporter, "Could not create surface context for colorType: %d\n", colorType);
|
||||
}
|
||||
|
||||
if (!surfaceContext->readPixels(dContext, actual.info(), actual.writable_addr(),
|
||||
actual.rowBytes(), {0, 0})) {
|
||||
if (!surfaceContext->readPixels(dContext, actual, {0, 0})) {
|
||||
// TODO: we need a better way to tell a priori if readPixels will work for an
|
||||
// arbitrary colorType
|
||||
#if 0
|
||||
@ -416,11 +415,7 @@ static void check_mipmaps(GrDirectContext* dContext,
|
||||
SkAssertResult(actual.tryAlloc(readbackII));
|
||||
actual.erase(SkColors::kTransparent);
|
||||
|
||||
bool result = dstFillContext->readPixels(dContext,
|
||||
actual.info(),
|
||||
actual.writable_addr(),
|
||||
actual.rowBytes(),
|
||||
{0, 0});
|
||||
bool result = dstFillContext->readPixels(dContext, actual, {0, 0});
|
||||
REPORTER_ASSERT(reporter, result);
|
||||
|
||||
SkString str;
|
||||
|
@ -42,8 +42,7 @@ static bool check_rect(GrDirectContext* dContext, GrSurfaceDrawContext* rtc, con
|
||||
readback.alloc(dstInfo);
|
||||
|
||||
readback.erase(~expectedValue);
|
||||
if (!rtc->readPixels(dContext, readback.info(), readback.writable_addr(), readback.rowBytes(),
|
||||
{rect.fLeft, rect.fTop})) {
|
||||
if (!rtc->readPixels(dContext, readback, {rect.fLeft, rect.fTop})) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -78,12 +78,12 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CopySurface, reporter, ctxInfo) {
|
||||
for (const SkIRect& srcRect : kSrcRects) {
|
||||
for (const SkIPoint& dstPoint : kDstPoints) {
|
||||
for (const SkImageInfo& ii: kImageInfos) {
|
||||
GrPixmap srcPM(ii, srcPixels.get(), kRowBytes);
|
||||
GrPixmap dstPM(ii, dstPixels.get(), kRowBytes);
|
||||
auto srcView = sk_gpu_test::MakeTextureProxyViewFromData(
|
||||
dContext, sRenderable, sOrigin, ii, srcPixels.get(),
|
||||
kRowBytes);
|
||||
dContext, sRenderable, sOrigin, srcPM);
|
||||
auto dstView = sk_gpu_test::MakeTextureProxyViewFromData(
|
||||
dContext, dRenderable, dOrigin, ii, dstPixels.get(),
|
||||
kRowBytes);
|
||||
dContext, dRenderable, dOrigin, dstPM);
|
||||
|
||||
// Should always work if the color type is RGBA, but may not work
|
||||
// for BGRA
|
||||
@ -162,8 +162,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CopySurface, reporter, ctxInfo) {
|
||||
}
|
||||
|
||||
sk_memset32(read.get(), 0, kW * kH);
|
||||
if (!dstContext->readPixels(
|
||||
dContext, ii, read.get(), kRowBytes, {0, 0})) {
|
||||
GrPixmap readPM(ii, read.get(), kRowBytes);
|
||||
if (!dstContext->readPixels(dContext, readPM, {0, 0})) {
|
||||
ERRORF(reporter, "Error calling readPixels");
|
||||
continue;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ static SkBitmap read_back(GrDirectContext* dContext, GrSurfaceDrawContext* rtc,
|
||||
SkBitmap bm;
|
||||
bm.allocPixels(dstII);
|
||||
|
||||
rtc->readPixels(dContext, dstII, bm.getAddr(0, 0), bm.rowBytes(), {0, 0});
|
||||
rtc->readPixels(dContext, bm.pixmap(), {0, 0});
|
||||
|
||||
return bm;
|
||||
}
|
||||
|
@ -50,8 +50,11 @@ void runFPTest(skiatest::Reporter* reporter, GrDirectContext* dContext,
|
||||
|
||||
for (auto origin : {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
|
||||
GrImageInfo info(colorType, kPremul_SkAlphaType, nullptr, {DEV_W, DEV_H});
|
||||
auto fpView = sk_gpu_test::MakeTextureProxyViewFromData(
|
||||
dContext, GrRenderable::kYes, origin, info, controlPixelData.begin(), 0);
|
||||
GrPixmap controlPixmap(info, controlPixelData.begin(), info.minRowBytes());
|
||||
auto fpView = sk_gpu_test::MakeTextureProxyViewFromData(dContext,
|
||||
GrRenderable::kYes,
|
||||
origin,
|
||||
controlPixmap);
|
||||
// Floating point textures are NOT supported everywhere
|
||||
if (!fpView) {
|
||||
continue;
|
||||
@ -60,7 +63,8 @@ void runFPTest(skiatest::Reporter* reporter, GrDirectContext* dContext,
|
||||
auto sContext = GrSurfaceContext::Make(dContext, std::move(fpView), info.colorInfo());
|
||||
REPORTER_ASSERT(reporter, sContext);
|
||||
|
||||
bool result = sContext->readPixels(dContext, info, readBuffer.begin(), 0, {0, 0});
|
||||
GrPixmap readPixmap(info, readBuffer.begin(), info.minRowBytes());
|
||||
bool result = sContext->readPixels(dContext, readPixmap, {0, 0});
|
||||
REPORTER_ASSERT(reporter, result);
|
||||
REPORTER_ASSERT(reporter,
|
||||
!memcmp(readBuffer.begin(), controlPixelData.begin(), readBuffer.bytes()));
|
||||
|
@ -587,7 +587,7 @@ static void run_test(GrDirectContext* dContext, const char* testName,
|
||||
const std::unique_ptr<GrSurfaceDrawContext>& rtc, const SkBitmap& gold,
|
||||
std::function<void(DrawMeshHelper*)> prepareFn,
|
||||
std::function<void(DrawMeshHelper*)> executeFn) {
|
||||
const int w = gold.width(), h = gold.height(), rowBytes = gold.rowBytes();
|
||||
const int w = gold.width(), h = gold.height();
|
||||
const uint32_t* goldPx = reinterpret_cast<const uint32_t*>(gold.getPixels());
|
||||
if (h != rtc->height() || w != rtc->width()) {
|
||||
ERRORF(reporter, "[%s] expectation and rtc not compatible (?).", testName);
|
||||
@ -598,11 +598,11 @@ static void run_test(GrDirectContext* dContext, const char* testName,
|
||||
return;
|
||||
}
|
||||
|
||||
SkAutoSTMalloc<kImageHeight * kImageWidth, uint32_t> resultPx(h * rowBytes);
|
||||
auto [resultPM, resultStorage] = GrPixmap::Allocate(gold.info());
|
||||
rtc->clear(SkPMColor4f::FromBytes_RGBA(0xbaaaaaad));
|
||||
rtc->addDrawOp(GrMeshTestOp::Make(dContext, prepareFn, executeFn));
|
||||
|
||||
rtc->readPixels(dContext, gold.info(), resultPx, rowBytes, {0, 0});
|
||||
rtc->readPixels(dContext, resultPM, {0, 0});
|
||||
|
||||
#ifdef WRITE_PNG_CONTEXT_TYPE
|
||||
#define STRINGIFY(X) #X
|
||||
@ -610,14 +610,13 @@ static void run_test(GrDirectContext* dContext, const char* testName,
|
||||
SkString filename;
|
||||
filename.printf("GrMeshTest_%s_%s.png", TOSTRING(WRITE_PNG_CONTEXT_TYPE), testName);
|
||||
SkDebugf("writing %s...\n", filename.c_str());
|
||||
ToolUtils::EncodeImageToFile(filename.c_str(), SkPixmap(gold.info(), resultPx, rowBytes),
|
||||
SkEncodedImageFormat::kPNG, 100);
|
||||
ToolUtils::EncodeImageToFile(filename.c_str(), resultPM, SkEncodedImageFormat::kPNG, 100);
|
||||
#endif
|
||||
|
||||
for (int y = 0; y < h; ++y) {
|
||||
for (int x = 0; x < w; ++x) {
|
||||
uint32_t expected = goldPx[y * kImageWidth + x];
|
||||
uint32_t actual = resultPx[y * kImageWidth + x];
|
||||
uint32_t actual = static_cast<uint32_t*>(resultPM.addr())[y * kImageWidth + x];
|
||||
if (expected != actual) {
|
||||
ERRORF(reporter, "[%s] pixel (%i,%i): got 0x%x expected 0x%x",
|
||||
testName, x, y, actual, expected);
|
||||
|
@ -231,7 +231,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrPipelineDynamicStateTest, reporter, ctxInfo
|
||||
rtc->addDrawOp(GrPipelineDynamicStateTestOp::Make(dContext, scissorTest, vbuff));
|
||||
auto ii = SkImageInfo::Make(kScreenSize, kScreenSize,
|
||||
kRGBA_8888_SkColorType, kPremul_SkAlphaType);
|
||||
rtc->readPixels(dContext, ii, resultPx, 4 * kScreenSize, {0, 0});
|
||||
GrPixmap resultPM(ii, resultPx, kScreenSize*sizeof(uint32_t));
|
||||
rtc->readPixels(dContext, resultPM, {0, 0});
|
||||
for (int y = 0; y < kScreenSize; ++y) {
|
||||
for (int x = 0; x < kScreenSize; ++x) {
|
||||
int expectedColorIdx;
|
||||
|
@ -272,9 +272,7 @@ DEF_GPUTEST(InitialTextureClear, reporter, baseOptions) {
|
||||
auto texCtx = GrSurfaceContext::Make(dContext, std::move(view), info);
|
||||
|
||||
readback.erase(kClearColor);
|
||||
if (texCtx->readPixels(
|
||||
dContext, readback.info(), readback.writable_addr(),
|
||||
readback.rowBytes(), {0, 0})) {
|
||||
if (texCtx->readPixels(dContext, readback, {0, 0})) {
|
||||
for (int i = 0; i < kSize * kSize; ++i) {
|
||||
if (!checkColor(combo, readback.addr32()[i])) {
|
||||
break;
|
||||
@ -306,8 +304,7 @@ DEF_GPUTEST(InitialTextureClear, reporter, baseOptions) {
|
||||
}
|
||||
|
||||
readback.erase(kClearColor);
|
||||
if (surfCtx->readPixels(dContext, readback.info(), readback.writable_addr(),
|
||||
readback.rowBytes(), {0, 0})) {
|
||||
if (surfCtx->readPixels(dContext, readback, {0, 0})) {
|
||||
for (int i = 0; i < kSize * kSize; ++i) {
|
||||
if (!checkColor(combo, readback.addr32()[i])) {
|
||||
break;
|
||||
@ -376,8 +373,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadOnlyTexture, reporter, context_info) {
|
||||
{
|
||||
SkAutoPixmapStorage read;
|
||||
read.alloc(srcPixmap.info());
|
||||
auto readResult = surfContext->readPixels(dContext, srcPixmap.info(),
|
||||
read.writable_addr(), 0, { 0, 0 });
|
||||
auto readResult = surfContext->readPixels(dContext, read, {0, 0});
|
||||
REPORTER_ASSERT(reporter, readResult);
|
||||
if (readResult) {
|
||||
comparePixels(srcPixmap, read, reporter);
|
||||
@ -388,8 +384,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadOnlyTexture, reporter, context_info) {
|
||||
SkAutoPixmapStorage write;
|
||||
write.alloc(srcPixmap.info());
|
||||
fillPixels(&write, [&srcPixmap](int x, int y) { return ~*srcPixmap.addr32(); });
|
||||
auto writeResult = surfContext->writePixels(dContext, srcPixmap.info(), write.addr(),
|
||||
0, {0, 0});
|
||||
auto writeResult = surfContext->writePixels(dContext, write, {0, 0});
|
||||
REPORTER_ASSERT(reporter, writeResult == (ioType == kRW_GrIOType));
|
||||
// Try the low level write.
|
||||
dContext->flushAndSubmit();
|
||||
|
@ -604,8 +604,7 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(OnFlushCallbackTest, reporter, ctxInfo) {
|
||||
SkBitmap readBack;
|
||||
readBack.allocN32Pixels(kFinalWidth, kFinalHeight);
|
||||
|
||||
SkAssertResult(rtc->readPixels(dContext, readBack.info(), readBack.getPixels(),
|
||||
readBack.rowBytes(), {0, 0}));
|
||||
SkAssertResult(rtc->readPixels(dContext, readBack.pixmap(), {0, 0}));
|
||||
|
||||
dContext->priv().testingOnly_flushAndRemoveOnFlushCallbackObject(&object);
|
||||
|
||||
|
@ -246,9 +246,9 @@ void render_fp(GrDirectContext* dContext,
|
||||
GrColor* outBuffer) {
|
||||
test_draw_op(dContext, rtc, std::move(fp));
|
||||
std::fill_n(outBuffer, rtc->width() * rtc->height(), 0);
|
||||
rtc->readPixels(dContext, SkImageInfo::Make(rtc->width(), rtc->height(), kRGBA_8888_SkColorType,
|
||||
kPremul_SkAlphaType),
|
||||
outBuffer, /*rowBytes=*/0, /*srcPt=*/{0, 0});
|
||||
auto ii = SkImageInfo::Make(rtc->dimensions(), kRGBA_8888_SkColorType, kPremul_SkAlphaType);
|
||||
GrPixmap resultPM(ii, outBuffer, rtc->width()*sizeof(uint32_t));
|
||||
rtc->readPixels(dContext, resultPM, {0, 0});
|
||||
}
|
||||
|
||||
// This class is responsible for reproducibly generating a random fragment processor.
|
||||
@ -413,7 +413,7 @@ bool log_texture_view(GrDirectContext* dContext, GrSurfaceProxyView src, SkStrin
|
||||
auto sContext = GrSurfaceContext::Make(dContext, std::move(src), ii.colorInfo());
|
||||
SkBitmap bm;
|
||||
SkAssertResult(bm.tryAllocPixels(ii));
|
||||
SkAssertResult(sContext->readPixels(dContext, ii, bm.getPixels(), bm.rowBytes(), {0, 0}));
|
||||
SkAssertResult(sContext->readPixels(dContext, bm.pixmap(), {0, 0}));
|
||||
return BipmapToBase64DataURI(bm, dst);
|
||||
}
|
||||
|
||||
|
@ -647,7 +647,7 @@ static void gpu_read_pixels_test_driver(skiatest::Reporter* reporter,
|
||||
REPORTER_ASSERT(reporter, result != GpuReadResult::kSuccess);
|
||||
} else if (readCT == kUnknown_SkColorType) {
|
||||
REPORTER_ASSERT(reporter, result != GpuReadResult::kSuccess);
|
||||
} else if (readAT == kUnknown_SkAlphaType) {
|
||||
} else if ((readAT == kUnknown_SkAlphaType) != (srcAT == kUnknown_SkAlphaType)) {
|
||||
REPORTER_ASSERT(reporter, result != GpuReadResult::kSuccess);
|
||||
} else if (!rules.fUncontainedRectSucceeds && !surfBounds.contains(rect)) {
|
||||
REPORTER_ASSERT(reporter, result != GpuReadResult::kSuccess);
|
||||
@ -714,8 +714,22 @@ static void gpu_read_pixels_test_driver(skiatest::Reporter* reporter,
|
||||
diffs[0], diffs[1], diffs[2], diffs[3]);
|
||||
});
|
||||
SkAutoPixmapStorage ref;
|
||||
ref.alloc(readInfo.makeWH(dstWriteRect.width(), dstWriteRect.height()));
|
||||
SkImageInfo refInfo = readInfo.makeDimensions(dstWriteRect.size());
|
||||
ref.alloc(refInfo);
|
||||
if (readAT == kUnknown_SkAlphaType) {
|
||||
// Do a spoofed read where src and dst alpha type are both kUnpremul. This will
|
||||
// allow SkPixmap readPixels to succeed and won't do any alpha type conversion.
|
||||
SkPixmap unpremulRef(refInfo.makeAlphaType(kUnpremul_SkAlphaType),
|
||||
ref.addr(),
|
||||
ref.rowBytes());
|
||||
SkPixmap unpremulSRc(srcPixels.info().makeAlphaType(kUnpremul_SkAlphaType),
|
||||
srcPixels.addr(),
|
||||
srcPixels.rowBytes());
|
||||
|
||||
unpremulSRc.readPixels(unpremulRef, srcReadRect.x(), srcReadRect.y());
|
||||
} else {
|
||||
srcPixels.readPixels(ref, srcReadRect.x(), srcReadRect.y());
|
||||
}
|
||||
// This is the part of dstPixels that should have been updated.
|
||||
SkPixmap actual;
|
||||
SkAssertResult(dstPixels.extractSubset(&actual, dstWriteRect));
|
||||
@ -755,9 +769,13 @@ static void gpu_read_pixels_test_driver(skiatest::Reporter* reporter,
|
||||
auto make_ref_f32_data = [](SkAlphaType srcAT, SkColorType srcCT) -> SkAutoPixmapStorage {
|
||||
// Make src data in F32 with srcAT. We will convert it to each color type we test to
|
||||
// initialize the src.
|
||||
const auto refInfo =
|
||||
auto surfInfo =
|
||||
SkImageInfo::Make(kW, kH, kRGBA_F32_SkColorType, srcAT, SkColorSpace::MakeSRGB());
|
||||
auto refSurf = SkSurface::MakeRaster(refInfo);
|
||||
// Can't make a kUnknown_SkAlphaType surface.
|
||||
if (srcAT == kUnknown_SkAlphaType) {
|
||||
surfInfo = surfInfo.makeAlphaType(kUnpremul_SkAlphaType);
|
||||
}
|
||||
auto refSurf = SkSurface::MakeRaster(surfInfo);
|
||||
static constexpr SkPoint kPts1[] = {{0, 0}, {kW, kH}};
|
||||
static constexpr SkColor kColors1[] = {SK_ColorGREEN, SK_ColorRED};
|
||||
SkPaint paint;
|
||||
@ -795,7 +813,15 @@ static void gpu_read_pixels_test_driver(skiatest::Reporter* reporter,
|
||||
const auto srcInfo = SkImageInfo::Make(kW, kH, srcCT, srcAT, SkColorSpace::MakeSRGB());
|
||||
SkAutoPixmapStorage srcPixels;
|
||||
srcPixels.alloc(srcInfo);
|
||||
refSurf->readPixels(srcPixels, 0, 0);
|
||||
SkPixmap readPixmap = srcPixels;
|
||||
// Spoof the alpha type to kUnpremul so the read will succeed without doing any conversion
|
||||
// (because we made our surface also be kUnpremul).
|
||||
if (srcAT == kUnknown_SkAlphaType) {
|
||||
readPixmap.reset(srcPixels.info().makeAlphaType(kUnpremul_SkAlphaType),
|
||||
srcPixels.addr(),
|
||||
srcPixels.rowBytes());
|
||||
}
|
||||
refSurf->readPixels(readPixmap, 0, 0);
|
||||
return srcPixels;
|
||||
};
|
||||
const std::vector<SkIRect> longRectArray = {
|
||||
@ -864,8 +890,7 @@ static void gpu_read_pixels_test_driver(skiatest::Reporter* reporter,
|
||||
readCTTestedThoroughly = {};
|
||||
for (int sat = 0; sat < kLastEnum_SkAlphaType; ++sat) {
|
||||
const auto srcAT = static_cast<SkAlphaType>(sat);
|
||||
if (srcAT == kUnknown_SkAlphaType ||
|
||||
(srcAT == kUnpremul_SkAlphaType && !rules.fAllowUnpremulSrc)) {
|
||||
if (srcAT == kUnpremul_SkAlphaType && !rules.fAllowUnpremulSrc) {
|
||||
continue;
|
||||
}
|
||||
for (int sct = 0; sct <= kLastEnum_SkColorType; ++sct) {
|
||||
@ -933,11 +958,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceContextReadPixels, reporter, ctxInfo)
|
||||
GrDirectContext* direct = ctxInfo.directContext();
|
||||
auto reader = std::function<GpuReadSrcFn<Surface>>(
|
||||
[direct](const Surface& surface, const SkIVector& offset, const SkPixmap& pixels) {
|
||||
if (surface->readPixels(direct,
|
||||
pixels.info(),
|
||||
pixels.writable_addr(),
|
||||
pixels.rowBytes(),
|
||||
{offset.fX, offset.fY})) {
|
||||
if (surface->readPixels(direct, pixels, {offset.fX, offset.fY})) {
|
||||
return GpuReadResult::kSuccess;
|
||||
} else {
|
||||
// Reading from a non-renderable format is not guaranteed to work on GL.
|
||||
@ -968,11 +989,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceContextReadPixels, reporter, ctxInfo)
|
||||
origin,
|
||||
renderable);
|
||||
if (surfContext) {
|
||||
surfContext->writePixels(direct,
|
||||
src.info(),
|
||||
src.addr(),
|
||||
src.rowBytes(),
|
||||
{0, 0});
|
||||
surfContext->writePixels(direct, src, {0, 0});
|
||||
}
|
||||
return surfContext;
|
||||
});
|
||||
|
@ -98,11 +98,15 @@ static void test_copy_to_surface(skiatest::Reporter* reporter,
|
||||
|
||||
for (auto renderable : {GrRenderable::kNo, GrRenderable::kYes}) {
|
||||
auto origin = dstContext->origin();
|
||||
auto srcView = sk_gpu_test::MakeTextureProxyViewFromData(
|
||||
dContext, renderable, origin,
|
||||
{GrColorType::kRGBA_8888, kPremul_SkAlphaType, nullptr, dstContext->width(),
|
||||
dstContext->height()},
|
||||
pixels.get(), 0);
|
||||
GrImageInfo info(GrColorType::kRGBA_8888,
|
||||
kPremul_SkAlphaType,
|
||||
nullptr,
|
||||
dstContext->dimensions());
|
||||
GrPixmap pixmap(info, pixels.get(), dstContext->width()*sizeof(uint32_t));
|
||||
auto srcView = sk_gpu_test::MakeTextureProxyViewFromData(dContext,
|
||||
renderable,
|
||||
origin,
|
||||
pixmap);
|
||||
// If this assert ever fails we can add a fallback to do copy as draw, but until then we can
|
||||
// be more restrictive.
|
||||
SkAssertResult(dstContext->testCopy(srcView.proxy()));
|
||||
|
@ -58,10 +58,9 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(RenderTargetContextTest, reporter, ctxInfo) {
|
||||
check_instantiation_status(reporter, rtCtx.get(), false);
|
||||
|
||||
SkImageInfo dstInfo = SkImageInfo::MakeN32Premul(kSize, kSize);
|
||||
SkAutoTMalloc<uint32_t> dstBuffer(kSize * kSize);
|
||||
static const size_t kRowBytes = sizeof(uint32_t) * kSize;
|
||||
auto [dstPM, dstStorage] = GrPixmap::Allocate(dstInfo);
|
||||
|
||||
bool result = rtCtx->readPixels(dContext, dstInfo, dstBuffer.get(), kRowBytes, {0, 0});
|
||||
bool result = rtCtx->readPixels(dContext, dstPM, {0, 0});
|
||||
REPORTER_ASSERT(reporter, result);
|
||||
|
||||
check_instantiation_status(reporter, rtCtx.get(), true);
|
||||
|
@ -126,12 +126,11 @@ void read_and_check_pixels(skiatest::Reporter* reporter,
|
||||
uint32_t* origData,
|
||||
const SkImageInfo& dstInfo, CheckFn checker, float error,
|
||||
const char* subtestName) {
|
||||
int w = dstInfo.width();
|
||||
int h = dstInfo.height();
|
||||
SkAutoTMalloc<uint32_t> readData(w * h);
|
||||
memset(readData.get(), 0, sizeof(uint32_t) * w * h);
|
||||
auto [w, h] = dstInfo.dimensions();
|
||||
auto [readPM, readStorage] = GrPixmap::Allocate(dstInfo);
|
||||
memset(readPM.addr(), 0, sizeof(uint32_t)*w*h);
|
||||
|
||||
if (!sContext->readPixels(dContext, dstInfo, readData.get(), 0, {0, 0})) {
|
||||
if (!sContext->readPixels(dContext, readPM, {0, 0})) {
|
||||
ERRORF(reporter, "Could not read pixels for %s.", subtestName);
|
||||
return;
|
||||
}
|
||||
@ -139,7 +138,7 @@ void read_and_check_pixels(skiatest::Reporter* reporter,
|
||||
for (int j = 0; j < h; ++j) {
|
||||
for (int i = 0; i < w; ++i) {
|
||||
uint32_t orig = origData[j * w + i];
|
||||
uint32_t read = readData[j * w + i];
|
||||
uint32_t read = static_cast<uint32_t*>(readPM.addr())[j * w + i];
|
||||
|
||||
if (!checker(orig, read, error)) {
|
||||
ERRORF(reporter, "Original 0x%08x, read back as 0x%08x in %s at %d, %d).", orig,
|
||||
@ -212,7 +211,8 @@ static void test_write_read(Encoding contextEncoding, Encoding writeEncoding, En
|
||||
auto writeII = SkImageInfo::Make(kW, kH, kRGBA_8888_SkColorType, kPremul_SkAlphaType,
|
||||
encoding_as_color_space(writeEncoding));
|
||||
auto data = make_data();
|
||||
if (!surfaceContext->writePixels(dContext, writeII, data.get(), 0, {0, 0})) {
|
||||
GrPixmap dataPM(writeII, data.get(), kW*sizeof(uint32_t));
|
||||
if (!surfaceContext->writePixels(dContext, dataPM, {0, 0})) {
|
||||
ERRORF(reporter, "Could not write %s to %s surface context.",
|
||||
encoding_as_str(writeEncoding), encoding_as_str(contextEncoding));
|
||||
return;
|
||||
|
@ -97,9 +97,10 @@ static void run_test(skiatest::Reporter* reporter, GrDirectContext* directContex
|
||||
SkRect::MakeWH(1,1));
|
||||
|
||||
GrColor result;
|
||||
rtc->readPixels(directContext,
|
||||
SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kPremul_SkAlphaType), &result,
|
||||
4, {0, 0});
|
||||
GrPixmap resultPM(SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kPremul_SkAlphaType),
|
||||
&result,
|
||||
sizeof(GrColor));
|
||||
rtc->readPixels(directContext, resultPM, {0, 0});
|
||||
|
||||
SkASSERT(expectedCrossProduct == a.cross(b));
|
||||
if (expectedCrossProduct > 0) {
|
||||
|
@ -729,8 +729,7 @@ static void test_surface_context_clear(skiatest::Reporter* reporter,
|
||||
readback.alloc(ii);
|
||||
|
||||
readback.erase(~expectedValue);
|
||||
surfaceContext->readPixels(dContext, readback.info(), readback.writable_addr(),
|
||||
readback.rowBytes(), {0, 0});
|
||||
surfaceContext->readPixels(dContext, readback, {0, 0});
|
||||
for (int y = 0; y < h; ++y) {
|
||||
for (int x = 0; x < w; ++x) {
|
||||
uint32_t pixel = readback.addr32()[y * w + x];
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "include/encode/SkPngEncoder.h"
|
||||
#include "include/utils/SkBase64.h"
|
||||
#include "src/core/SkAutoPixmapStorage.h"
|
||||
#include "src/core/SkUtils.h"
|
||||
#include "src/gpu/GrDirectContextPriv.h"
|
||||
#include "src/gpu/GrDrawingManager.h"
|
||||
@ -26,20 +27,22 @@ void TestReadPixels(skiatest::Reporter* reporter,
|
||||
uint32_t expectedPixelValues[],
|
||||
const char* testName) {
|
||||
int pixelCnt = srcContext->width() * srcContext->height();
|
||||
SkAutoTMalloc<uint32_t> pixels(pixelCnt);
|
||||
memset(pixels.get(), 0, sizeof(uint32_t)*pixelCnt);
|
||||
SkImageInfo ii = SkImageInfo::Make(srcContext->dimensions(),
|
||||
kRGBA_8888_SkColorType,
|
||||
kPremul_SkAlphaType);
|
||||
SkAutoPixmapStorage pm;
|
||||
pm.alloc(ii);
|
||||
pm.erase(SK_ColorTRANSPARENT);
|
||||
|
||||
SkImageInfo ii = SkImageInfo::Make(srcContext->width(), srcContext->height(),
|
||||
kRGBA_8888_SkColorType, kPremul_SkAlphaType);
|
||||
bool read = srcContext->readPixels(dContext, ii, pixels.get(), 0, {0, 0});
|
||||
bool read = srcContext->readPixels(dContext, pm, {0, 0});
|
||||
if (!read) {
|
||||
ERRORF(reporter, "%s: Error reading from texture.", testName);
|
||||
}
|
||||
|
||||
for (int i = 0; i < pixelCnt; ++i) {
|
||||
if (pixels.get()[i] != expectedPixelValues[i]) {
|
||||
if (pm.addr32()[i] != expectedPixelValues[i]) {
|
||||
ERRORF(reporter, "%s: Error, pixel value %d should be 0x%08x, got 0x%08x.",
|
||||
testName, i, expectedPixelValues[i], pixels.get()[i]);
|
||||
testName, i, expectedPixelValues[i], pm.addr32()[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -50,18 +53,18 @@ void TestWritePixels(skiatest::Reporter* reporter,
|
||||
GrSurfaceContext* dstContext,
|
||||
bool expectedToWork,
|
||||
const char* testName) {
|
||||
int pixelCnt = dstContext->width() * dstContext->height();
|
||||
SkAutoTMalloc<uint32_t> pixels(pixelCnt);
|
||||
for (int y = 0; y < dstContext->width(); ++y) {
|
||||
for (int x = 0; x < dstContext->height(); ++x) {
|
||||
pixels.get()[y * dstContext->width() + x] =
|
||||
SkColorToPremulGrColor(SkColorSetARGB(2*y, x, y, x + y));
|
||||
SkImageInfo ii = SkImageInfo::Make(dstContext->dimensions(),
|
||||
kRGBA_8888_SkColorType,
|
||||
kPremul_SkAlphaType);
|
||||
SkAutoPixmapStorage pm;
|
||||
pm.alloc(ii);
|
||||
for (int y = 0; y < dstContext->height(); ++y) {
|
||||
for (int x = 0; x < dstContext->width(); ++x) {
|
||||
*pm.writable_addr32(x, y) = SkColorToPremulGrColor(SkColorSetARGB(2*y, x, y, x + y));
|
||||
}
|
||||
}
|
||||
|
||||
SkImageInfo ii = SkImageInfo::Make(dstContext->width(), dstContext->height(),
|
||||
kRGBA_8888_SkColorType, kPremul_SkAlphaType);
|
||||
bool write = dstContext->writePixels(dContext, ii, pixels.get(), 0, {0, 0});
|
||||
bool write = dstContext->writePixels(dContext, pm, {0, 0});
|
||||
if (!write) {
|
||||
if (expectedToWork) {
|
||||
ERRORF(reporter, "%s: Error writing to texture.", testName);
|
||||
@ -74,7 +77,7 @@ void TestWritePixels(skiatest::Reporter* reporter,
|
||||
return;
|
||||
}
|
||||
|
||||
TestReadPixels(reporter, dContext, dstContext, pixels.get(), testName);
|
||||
TestReadPixels(reporter, dContext, dstContext, pm.writable_addr32(0, 0), testName);
|
||||
}
|
||||
|
||||
void TestCopyFromSurface(skiatest::Reporter* reporter,
|
||||
|
@ -5,54 +5,57 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "tools/gpu/ProxyUtils.h"
|
||||
|
||||
#include "include/core/SkColor.h"
|
||||
#include "include/gpu/GrBackendSurface.h"
|
||||
#include "include/gpu/GrDirectContext.h"
|
||||
#include "src/gpu/GrDirectContextPriv.h"
|
||||
#include "src/gpu/GrDrawingManager.h"
|
||||
#include "src/gpu/GrGpu.h"
|
||||
#include "src/gpu/GrImageInfo.h"
|
||||
#include "src/gpu/GrPixmap.h"
|
||||
#include "src/gpu/GrProgramInfo.h"
|
||||
#include "src/gpu/GrProxyProvider.h"
|
||||
#include "src/gpu/GrSurfaceContext.h"
|
||||
#include "src/gpu/SkGr.h"
|
||||
#include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h"
|
||||
#include "tools/gpu/ProxyUtils.h"
|
||||
|
||||
namespace sk_gpu_test {
|
||||
|
||||
GrSurfaceProxyView MakeTextureProxyViewFromData(GrDirectContext* dContext,
|
||||
GrRenderable renderable,
|
||||
GrSurfaceOrigin origin,
|
||||
const GrImageInfo& imageInfo,
|
||||
const void* data,
|
||||
size_t rowBytes) {
|
||||
GrPixmap pixmap) {
|
||||
if (dContext->abandoned()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const GrCaps* caps = dContext->priv().caps();
|
||||
|
||||
const GrBackendFormat format = caps->getDefaultBackendFormat(imageInfo.colorType(), renderable);
|
||||
const GrBackendFormat format = caps->getDefaultBackendFormat(pixmap.colorType(), renderable);
|
||||
if (!format.isValid()) {
|
||||
return {};
|
||||
}
|
||||
GrSwizzle swizzle = caps->getReadSwizzle(format, imageInfo.colorType());
|
||||
GrSwizzle swizzle = caps->getReadSwizzle(format, pixmap.colorType());
|
||||
|
||||
sk_sp<GrTextureProxy> proxy;
|
||||
proxy = dContext->priv().proxyProvider()->createProxy(format, imageInfo.dimensions(),
|
||||
renderable, 1, GrMipmapped::kNo,
|
||||
SkBackingFit::kExact, SkBudgeted::kYes,
|
||||
proxy = dContext->priv().proxyProvider()->createProxy(format,
|
||||
pixmap.dimensions(),
|
||||
renderable,
|
||||
/*sample count*/ 1,
|
||||
GrMipmapped::kNo,
|
||||
SkBackingFit::kExact,
|
||||
SkBudgeted::kYes,
|
||||
GrProtected::kNo);
|
||||
if (!proxy) {
|
||||
return {};
|
||||
}
|
||||
GrSurfaceProxyView view(proxy, origin, swizzle);
|
||||
auto sContext = GrSurfaceContext::Make(dContext, std::move(view), imageInfo.colorInfo());
|
||||
auto sContext = GrSurfaceContext::Make(dContext, std::move(view), pixmap.colorInfo());
|
||||
if (!sContext) {
|
||||
return {};
|
||||
}
|
||||
if (!sContext->writePixels(dContext, imageInfo, data, rowBytes, {0, 0})) {
|
||||
if (!sContext->writePixels(dContext, pixmap, {0, 0})) {
|
||||
return {};
|
||||
}
|
||||
return sContext->readSurfaceView();
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
class GrDirectContext;
|
||||
class GrProgramInfo;
|
||||
class GrPixmap;
|
||||
|
||||
namespace sk_gpu_test {
|
||||
|
||||
@ -22,9 +23,7 @@ namespace sk_gpu_test {
|
||||
GrSurfaceProxyView MakeTextureProxyViewFromData(GrDirectContext*,
|
||||
GrRenderable,
|
||||
GrSurfaceOrigin,
|
||||
const GrImageInfo&,
|
||||
const void* data,
|
||||
size_t rowBytes);
|
||||
GrPixmap pixmap);
|
||||
|
||||
GrProgramInfo* CreateProgramInfo(const GrCaps*,
|
||||
SkArenaAlloc*,
|
||||
|
Loading…
Reference in New Issue
Block a user