GrConvertPixels takes pixmaps

Add GrCPixmap, a GrPixmap but with const void* instead of void*. Share
impl via template base class GrPixmapBase.

Change-Id: I7dfdf24a73c1bc8557ff7b90f93a9399da2f3f75
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/350022
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Brian Salomon 2021-03-30 16:14:37 -04:00 committed by Skia Commit-Bot
parent 48ad43ab0a
commit 5392c94fe8
25 changed files with 263 additions and 204 deletions

View File

@ -3,21 +3,17 @@
#include "include/core/SkCanvas.h"
#include "include/core/SkGraphics.h"
#include "include/core/SkPicture.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "include/private/SkSLDefines.h"
#include "src/core/SkOSFile.h"
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrDirectContextPriv.h"
#include "src/utils/SkOSPath.h"
#include "tools/DDLPromiseImageHelper.h"
#include "tools/DDLTileHelper.h"
#include "tools/ToolUtils.h"
#include "tools/flags/CommandLineFlags.h"
#include "tools/gpu/GrContextFactory.h"
#include "tools/gpu/TestContext.h"

View File

@ -18,6 +18,7 @@
#include "src/core/SkUtils.h"
#include "src/gpu/GrColor.h"
#include "src/gpu/GrImageInfo.h"
#include "src/gpu/GrPixmap.h"
struct ETC1Block {
uint32_t fHigh;
@ -507,43 +508,36 @@ static inline void append_clamp_gamut(SkRasterPipeline* pipeline) {
pipeline->append_gamut_clamp_if_normalized(fakeII);
}
bool GrConvertPixels(const GrImageInfo& dstInfo, void* dst, size_t dstRB,
const GrImageInfo& srcInfo, const void* src, size_t srcRB,
bool flipY) {
bool GrConvertPixels(const GrPixmap& dst, const GrCPixmap& src, bool flipY) {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
if (srcInfo.colorType() == GrColorType::kRGB_888) {
if (src.colorType() == GrColorType::kRGB_888) {
// We don't expect to have to convert from this format.
return false;
}
if (srcInfo.dimensions().isEmpty() || dstInfo.dimensions().isEmpty()) {
if (src.dimensions().isEmpty() || dst.dimensions().isEmpty()) {
return false;
}
if (srcInfo.colorType() == GrColorType::kUnknown ||
dstInfo.colorType() == GrColorType::kUnknown) {
if (src.colorType() == GrColorType::kUnknown || dst.colorType() == GrColorType::kUnknown) {
return false;
}
if (!src || !dst) {
if (!src.hasPixels() || !dst.hasPixels()) {
return false;
}
if (dstInfo.dimensions() != srcInfo.dimensions()) {
if (dst.dimensions() != src.dimensions()) {
return false;
}
if (dstRB < dstInfo.minRowBytes() || srcRB < srcInfo.minRowBytes()) {
return false;
}
if (dstInfo.colorType() == GrColorType::kRGB_888) {
if (dst.colorType() == GrColorType::kRGB_888) {
// SkRasterPipeline doesn't handle writing to RGB_888. So we have it write to RGB_888x and
// then do another conversion that does the 24bit packing.
auto tempDstInfo = dstInfo.makeColorType(GrColorType::kRGB_888x);
auto tempRB = tempDstInfo.minRowBytes();
std::unique_ptr<char[]> tempDst(new char[tempRB * tempDstInfo.height()]);
if (!GrConvertPixels(tempDstInfo, tempDst.get(), tempRB, srcInfo, src, srcRB, flipY)) {
// then do another conversion that does the 24bit packing. We could be cleverer and skip the
// temp pixmap if this is the only conversion but this is rare so keeping it simple.
GrPixmap temp = GrPixmap::Allocate(dst.info().makeColorType(GrColorType::kRGB_888x));
if (!GrConvertPixels(temp, src, flipY)) {
return false;
}
auto* tRow = reinterpret_cast<const char*>(tempDst.get());
auto* dRow = reinterpret_cast<char*>(dst);
for (int y = 0; y < dstInfo.height(); ++y, tRow += tempRB, dRow += dstRB) {
for (int x = 0; x < dstInfo.width(); ++x) {
auto* tRow = reinterpret_cast<const char*>(temp.addr());
auto* dRow = reinterpret_cast<char*>(dst.addr());
for (int y = 0; y < dst.height(); ++y, tRow += temp.rowBytes(), dRow += dst.rowBytes()) {
for (int x = 0; x < dst.width(); ++x) {
auto t = reinterpret_cast<const uint32_t*>(tRow + x * sizeof(uint32_t));
auto d = reinterpret_cast<uint32_t*>(dRow + x * 3);
memcpy(d, t, 3);
@ -552,31 +546,32 @@ bool GrConvertPixels(const GrImageInfo& dstInfo, void* dst, size_t dstRB,
return true;
}
size_t srcBpp = srcInfo.bpp();
size_t dstBpp = dstInfo.bpp();
size_t srcBpp = src.info().bpp();
size_t dstBpp = dst.info().bpp();
// SkRasterPipeline operates on row-pixels not row-bytes.
SkASSERT(dstRB % dstBpp == 0);
SkASSERT(srcRB % srcBpp == 0);
SkASSERT(dst.rowBytes() % dstBpp == 0);
SkASSERT(src.rowBytes() % srcBpp == 0);
bool premul = srcInfo.alphaType() == kUnpremul_SkAlphaType &&
dstInfo.alphaType() == kPremul_SkAlphaType;
bool unpremul = srcInfo.alphaType() == kPremul_SkAlphaType &&
dstInfo.alphaType() == kUnpremul_SkAlphaType;
bool premul = src.alphaType() == kUnpremul_SkAlphaType &&
dst.alphaType() == kPremul_SkAlphaType;
bool unpremul = src.alphaType() == kPremul_SkAlphaType &&
dst.alphaType() == kUnpremul_SkAlphaType;
bool alphaOrCSConversion =
premul || unpremul || !SkColorSpace::Equals(srcInfo.colorSpace(), dstInfo.colorSpace());
premul || unpremul || !SkColorSpace::Equals(src.colorSpace(), dst.colorSpace());
if (srcInfo.colorType() == dstInfo.colorType() && !alphaOrCSConversion) {
size_t tightRB = dstBpp * dstInfo.width();
if (src.colorType() == dst.colorType() && !alphaOrCSConversion) {
size_t tightRB = dstBpp * dst.width();
if (flipY) {
dst = static_cast<char*>(dst) + dstRB * (dstInfo.height() - 1);
for (int y = 0; y < dstInfo.height(); ++y) {
memcpy(dst, src, tightRB);
src = static_cast<const char*>(src) + srcRB;
dst = static_cast< char*>(dst) - dstRB;
auto s = static_cast<const char*>(src.addr());
auto d = SkTAddOffset<char>(dst.addr(), dst.rowBytes()*(dst.height() - 1));
for (int y = 0; y < dst.height(); ++y, d -= dst.rowBytes(), s += src.rowBytes()) {
memcpy(d, s, tightRB);
}
} else {
SkRectMemcpy(dst, dstRB, src, srcRB, tightRB, srcInfo.height());
SkRectMemcpy(dst.addr(), dst.rowBytes(),
src.addr(), src.rowBytes(),
tightRB, src.height());
}
return true;
}
@ -584,34 +579,38 @@ bool GrConvertPixels(const GrImageInfo& dstInfo, void* dst, size_t dstRB,
SkRasterPipeline::StockStage load;
bool srcIsNormalized;
bool srcIsSRGB;
auto loadSwizzle =
get_load_and_src_swizzle(srcInfo.colorType(), &load, &srcIsNormalized, &srcIsSRGB);
auto loadSwizzle = get_load_and_src_swizzle(src.colorType(),
&load,
&srcIsNormalized,
&srcIsSRGB);
SkRasterPipeline::StockStage store;
LumMode lumMode;
bool dstIsNormalized;
bool dstIsSRGB;
auto storeSwizzle = get_dst_swizzle_and_store(dstInfo.colorType(), &store, &lumMode,
&dstIsNormalized, &dstIsSRGB);
auto storeSwizzle = get_dst_swizzle_and_store(dst.colorType(),
&store,
&lumMode,
&dstIsNormalized,
&dstIsSRGB);
bool clampGamut;
SkTLazy<SkColorSpaceXformSteps> steps;
GrSwizzle loadStoreSwizzle;
if (alphaOrCSConversion) {
steps.init(srcInfo.colorSpace(), srcInfo.alphaType(),
dstInfo.colorSpace(), dstInfo.alphaType());
clampGamut = dstIsNormalized && dstInfo.alphaType() == kPremul_SkAlphaType;
steps.init(src.colorSpace(), src.alphaType(), dst.colorSpace(), dst.alphaType());
clampGamut = dstIsNormalized && dst.alphaType() == kPremul_SkAlphaType;
} else {
clampGamut =
dstIsNormalized && !srcIsNormalized && dstInfo.alphaType() == kPremul_SkAlphaType;
clampGamut = dstIsNormalized && !srcIsNormalized && dst.alphaType() == kPremul_SkAlphaType;
if (!clampGamut) {
loadStoreSwizzle = GrSwizzle::Concat(loadSwizzle, storeSwizzle);
}
}
int cnt = 1;
int height = srcInfo.height();
SkRasterPipeline_MemoryCtx srcCtx{const_cast<void*>(src), SkToInt(srcRB / srcBpp)},
dstCtx{ dst , SkToInt(dstRB / dstBpp)};
int height = src.height();
SkRasterPipeline_MemoryCtx
srcCtx{const_cast<void*>(src.addr()), SkToInt(src.rowBytes()/srcBpp)},
dstCtx{ dst.addr(), SkToInt(dst.rowBytes()/dstBpp)};
if (flipY) {
// It *almost* works to point the src at the last row and negate the stride and run the
@ -619,7 +618,7 @@ bool GrConvertPixels(const GrImageInfo& dstInfo, void* dst, size_t dstRB,
// variables so it winds up relying on unsigned overflow math. It works out in practice
// but UBSAN says "no!" as it's technically undefined and in theory a compiler could emit
// code that didn't do what is intended. So we go one row at a time. :(
srcCtx.pixels = static_cast<char*>(srcCtx.pixels) + srcRB * (height - 1);
srcCtx.pixels = static_cast<char*>(srcCtx.pixels) + src.rowBytes()*(height - 1);
std::swap(cnt, height);
}
@ -669,9 +668,9 @@ bool GrConvertPixels(const GrImageInfo& dstInfo, void* dst, size_t dstRB,
loadStoreSwizzle.apply(&pipeline);
}
pipeline.append(store, &dstCtx);
pipeline.run(0, 0, srcInfo.width(), height);
srcCtx.pixels = static_cast<char*>(srcCtx.pixels) - srcRB;
dstCtx.pixels = static_cast<char*>(dstCtx.pixels) + dstRB;
pipeline.run(0, 0, src.width(), height);
srcCtx.pixels = static_cast<char*>(srcCtx.pixels) - src.rowBytes();
dstCtx.pixels = static_cast<char*>(dstCtx.pixels) + dst.rowBytes();
}
return true;
}

View File

@ -10,8 +10,12 @@
#include "include/core/SkColor.h"
#include "include/private/GrTypesPriv.h"
#include "src/gpu/GrPixmap.h"
#include "src/gpu/GrSwizzle.h"
#include "include/private/SkTArray.h"
class GrImageInfo;
class GrCPixmap;
class GrPixmap;
class SkPixmap;
size_t GrNumBlocks(SkImage::CompressionType, SkISize baseDimensions);
@ -32,17 +36,7 @@ size_t GrComputeTightCombinedBufferSize(size_t bytesPerPixel, SkISize baseDimens
void GrFillInCompressedData(SkImage::CompressionType, SkISize dimensions, GrMipmapped, char* dest,
const SkColor4f& color);
// Swizzle param is applied after loading and before converting from srcInfo to dstInfo.
bool GrConvertPixels(const GrImageInfo& dstInfo, void* dst, size_t dstRB,
const GrImageInfo& srcInfo, const void* src, size_t srcRB,
bool flipY = false);
// Convenience version for src/dst pixmaps.
inline bool GrConvertPixels(const GrPixmap& dst, const GrPixmap& src, bool flipY = false) {
return GrConvertPixels(dst.info(), dst.addr(), dst.rowBytes(),
src.info(), src.addr(), src.rowBytes(),
flipY);
}
bool GrConvertPixels(const GrPixmap& dst, const GrCPixmap& src, bool flipY = false);
/** Clears the dst image to a constant color. */
bool GrClearImage(const GrImageInfo& dstInfo, void* dst, size_t dstRB, SkColor4f color);

View File

@ -44,6 +44,10 @@ public:
return {this->colorType(), at, this->refColorSpace(), this->width(), this->height()};
}
GrImageInfo makeColorSpace(sk_sp<SkColorSpace> cs) const {
return {this->colorType(), this->alphaType(), std::move(cs), this->width(), this->height()};
}
GrImageInfo makeDimensions(SkISize dimensions) const {
return {this->colorType(), this->alphaType(), this->refColorSpace(), dimensions};
}

View File

@ -114,12 +114,12 @@ void GrOpFlushState::doUpload(GrDeferredTextureUploadFn& upload,
if (supportedWrite.fColorType != colorType ||
(!fGpu->caps()->writePixelsRowBytesSupport() && rowBytes != tightRB)) {
tmpPixels.reset(new char[height * tightRB]);
// Use kUnpremul to ensure no alpha type conversions or clamping occur.
static constexpr auto kAT = kUnpremul_SkAlphaType;
GrImageInfo srcInfo(colorType, kAT, nullptr, width, height);
GrImageInfo tmpInfo(supportedWrite.fColorType, kAT, nullptr, width,
height);
if (!GrConvertPixels(tmpInfo, tmpPixels.get(), tightRB, srcInfo, buffer, rowBytes)) {
// Use kUnknown to ensure no alpha type conversions or clamping occur.
static constexpr auto kAT = kUnknown_SkAlphaType;
GrImageInfo srcInfo(colorType, kAT, nullptr, width, height);
GrImageInfo tmpInfo(supportedWrite.fColorType, kAT, nullptr, width, height);
if (!GrConvertPixels( GrPixmap(tmpInfo, tmpPixels.get(), tightRB ),
GrCPixmap(srcInfo, buffer, rowBytes))) {
return false;
}
rowBytes = tightRB;

View File

@ -12,39 +12,12 @@
#include "include/core/SkPixmap.h"
#include "src/gpu/GrImageInfo.h"
class GrPixmap {
template <typename T, typename DERIVED> class GrPixmapBase {
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; }
T* addr() const { return fAddr; }
size_t rowBytes() const { return fRowBytes; }
bool hasPixels() const { return SkToBool(fAddr); }
@ -56,6 +29,7 @@ public:
SkISize dimensions() const { return fInfo.dimensions(); }
GrColorType colorType() const { return fInfo.colorType(); }
SkAlphaType alphaType() const { return fInfo.alphaType(); }
SkColorSpace* colorSpace() const { return fInfo.colorSpace(); }
/**
* Map this pixmap to a rect in a surface of indicated dimensions at offset surfacePt. Clip the
@ -64,29 +38,107 @@ public:
* 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) {
DERIVED 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();
T* addr = static_cast<sknonstd::copy_const_t<char, T>*>(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};
return DERIVED{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) {
protected:
GrPixmapBase() = default;
GrPixmapBase(const GrPixmapBase& that) = default;
GrPixmapBase(GrPixmapBase&& that) = default;
GrPixmapBase& operator=(const GrPixmapBase& that) = default;
GrPixmapBase& operator=(GrPixmapBase&& that) = default;
GrPixmapBase(GrImageInfo info, T* addr, size_t rowBytes)
: fAddr(addr), fRowBytes(rowBytes), fInfo(std::move(info)) {
if (fRowBytes < info.minRowBytes() || !addr) {
*this = {};
}
}
GrPixmapBase(GrImageInfo info, sk_sp<SkData> storage, size_t rowBytes)
: GrPixmapBase(std::move(info), const_cast<void*>(storage->data()), rowBytes) {
fPixelStorage = std::move(storage);
}
void* fAddr = nullptr;
private:
T* fAddr = nullptr;
size_t fRowBytes = 0;
GrImageInfo fInfo;
sk_sp<SkData> fPixelStorage;
};
/** A pixmap with mutable pixels. */
class GrPixmap : public GrPixmapBase<void, 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) : GrPixmapBase(info, addr, rowBytes) {}
/* implicit */ GrPixmap(const SkPixmap& pixmap)
: GrPixmapBase(pixmap.info(), pixmap.writable_addr(), pixmap.rowBytes()) {}
/**
* Returns a GrPixmap that owns its backing store. Copies of the pixmap (as GrPixmap or
* GrCPixmap) 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);
}
private:
GrPixmap(GrImageInfo info, sk_sp<SkData> storage, size_t rowBytes)
: GrPixmapBase(std::move(info), std::move(storage), rowBytes) {}
};
/**
* A pixmap with immutable pixels. Note that this pixmap need not be the unique owner of the pixels
* and thus it is context-dependent whether the pixels could be manipulated externally.
*/
class GrCPixmap : public GrPixmapBase<const void, GrCPixmap> {
public:
GrCPixmap() = default;
GrCPixmap(const GrCPixmap&) = default;
GrCPixmap(GrCPixmap&&) = default;
GrCPixmap& operator=(const GrCPixmap&) = default;
GrCPixmap& operator=(GrCPixmap&&) = default;
/* implicit*/ GrCPixmap(const GrPixmap& pixmap) {
if (pixmap.pixelStorage()) {
*this = GrCPixmap(pixmap.info(), pixmap.pixelStorage(), pixmap.rowBytes());
} else {
*this = GrCPixmap(pixmap.info(), pixmap.addr(), pixmap.rowBytes());
}
}
/* implicit */ GrCPixmap(const SkPixmap& pixmap)
: GrPixmapBase(pixmap.info(), pixmap.addr(), pixmap.rowBytes()) {}
GrCPixmap(GrImageInfo info, const void* addr, size_t rowBytes)
: GrPixmapBase(info, addr, rowBytes) {}
private:
GrCPixmap(GrImageInfo info, sk_sp<SkData> storage, size_t rowBytes)
: GrPixmapBase(info, std::move(storage), rowBytes) {}
};
#endif

View File

@ -620,9 +620,10 @@ static bool prepare_level(const GrMipLevel& inLevel,
data->reset(new char[tempRB * dimensions.fHeight]);
outLevel->fPixels = data->get();
outLevel->fRowBytes = tempRB;
GrImageInfo srcInfo(origColorType, kUnpremul_SkAlphaType, nullptr, dimensions);
GrImageInfo srcInfo( origColorType, kUnpremul_SkAlphaType, nullptr, dimensions);
GrImageInfo dstInfo(allowedColorType, kUnpremul_SkAlphaType, nullptr, dimensions);
return GrConvertPixels(dstInfo, data->get(), tempRB, srcInfo, inLevel.fPixels, actualRB);
return GrConvertPixels( GrPixmap(dstInfo, data->get(), tempRB),
GrCPixmap(srcInfo, inLevel.fPixels, actualRB));
}
GrColorType GrResourceProvider::prepareLevels(const GrBackendFormat& format,

View File

@ -354,7 +354,7 @@ bool GrSurfaceContext::readPixels(GrDirectContext* dContext, GrPixmap dst, SkIPo
return true;
}
bool GrSurfaceContext::writePixels(GrDirectContext* dContext, GrPixmap src, SkIPoint pt) {
bool GrSurfaceContext::writePixels(GrDirectContext* dContext, GrCPixmap src, SkIPoint pt) {
ASSERT_SINGLE_OWNER
RETURN_FALSE_IF_ABANDONED
SkDEBUGCODE(this->validate();)
@ -1323,9 +1323,8 @@ GrSurfaceContext::PixelTransferResult GrSurfaceContext::transferPixels(GrColorTy
void* dst, const void* src) {
GrImageInfo srcInfo(supportedRead.fColorType, at, nullptr, w, h);
GrImageInfo dstInfo(dstCT, at, nullptr, w, h);
GrConvertPixels(dstInfo, dst, dstInfo.minRowBytes(),
srcInfo, src, srcInfo.minRowBytes(),
/* flipY = */ false);
GrConvertPixels( GrPixmap(dstInfo, dst, dstInfo.minRowBytes()),
GrCPixmap(srcInfo, src, srcInfo.minRowBytes()));
};
}
return result;

View File

@ -134,7 +134,7 @@ public:
* @param src source for the write
* @param dstPt offset w/in the surface context at which to write
*/
bool writePixels(GrDirectContext* dContext, GrPixmap src, SkIPoint dstPt);
bool writePixels(GrDirectContext* dContext, GrCPixmap src, SkIPoint dstPt);
GrSurfaceProxy* asSurfaceProxy() { return fReadView.proxy(); }
const GrSurfaceProxy* asSurfaceProxy() const { return fReadView.proxy(); }

View File

@ -6,6 +6,8 @@
*/
#include "src/gpu/gl/GrGLContext.h"
#include "include/gpu/GrContextOptions.h"
#include "src/gpu/gl/GrGLGLSL.h"
#ifdef SK_BUILD_FOR_ANDROID

View File

@ -227,7 +227,8 @@ static SkColor4f get_expected_color(SkColor4f orig, GrColorType ct) {
// Read back to SkColor4f.
SkColor4f result;
GrImageInfo resultII(GrColorType::kRGBA_F32, kUnpremul_SkAlphaType, nullptr, {1, 1});
GrConvertPixels(resultII, &result.fR, sizeof(result), ii, data.get(), ii.minRowBytes());
GrConvertPixels(GrPixmap(resultII, &result.fR, sizeof(result)),
GrPixmap( ii, data.get(), ii.minRowBytes()));
return result;
}

View File

@ -78,8 +78,8 @@ 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);
GrCPixmap srcPM(ii, srcPixels.get(), kRowBytes);
GrPixmap dstPM(ii, dstPixels.get(), kRowBytes);
auto srcView = sk_gpu_test::MakeTextureProxyViewFromData(
dContext, sRenderable, sOrigin, srcPM);
auto dstView = sk_gpu_test::MakeTextureProxyViewFromData(

View File

@ -50,7 +50,7 @@ void runFPTest(skiatest::Reporter* reporter, GrDirectContext* dContext,
for (auto origin : {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
GrImageInfo info(colorType, kPremul_SkAlphaType, nullptr, {DEV_W, DEV_H});
GrPixmap controlPixmap(info, controlPixelData.begin(), info.minRowBytes());
GrCPixmap controlPixmap(info, controlPixelData.begin(), info.minRowBytes());
auto fpView = sk_gpu_test::MakeTextureProxyViewFromData(dContext,
GrRenderable::kYes,
origin,

View File

@ -14,6 +14,7 @@
#include "include/private/SkTemplates.h"
#include "src/core/SkMatrixProvider.h"
#include "src/core/SkTLazy.h"
#include "src/gpu/GrColorInfo.h"
#include "src/shaders/SkColorShader.h"
#include "tests/Test.h"

View File

@ -9,6 +9,7 @@
*/
#include "include/core/SkCanvas.h"
#include "include/core/SkColorPriv.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkDocument.h"
#include "include/core/SkFont.h"
@ -18,6 +19,7 @@
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTextBlob.h"
#include "src/gpu/GrCaps.h"
#include "src/utils/SkMultiPictureDocument.h"
#include "tests/Test.h"
#include "tools/SkSharingProc.h"

View File

@ -6,8 +6,11 @@
*/
#include "include/core/SkCanvas.h"
#include "include/core/SkColorPriv.h"
#include "include/core/SkImage.h"
#include "include/core/SkSurface.h"
#include "include/private/SkColorData.h"
#include "include/private/SkHalf.h"
#include "include/private/SkImageInfoPriv.h"
#include "include/utils/SkNWayCanvas.h"
#include "src/core/SkMathPriv.h"

View File

@ -102,7 +102,7 @@ static void test_copy_to_surface(skiatest::Reporter* reporter,
kPremul_SkAlphaType,
nullptr,
dstContext->dimensions());
GrPixmap pixmap(info, pixels.get(), dstContext->width()*sizeof(uint32_t));
GrCPixmap pixmap(info, pixels.get(), dstContext->width()*sizeof(uint32_t));
auto srcView = sk_gpu_test::MakeTextureProxyViewFromData(dContext,
renderable,
origin,

View File

@ -211,7 +211,7 @@ 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();
GrPixmap dataPM(writeII, data.get(), kW*sizeof(uint32_t));
GrCPixmap 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));

View File

@ -13,6 +13,7 @@
#include "include/core/SkSurface.h"
#include "include/effects/SkRuntimeEffect.h"
#include "include/gpu/GrDirectContext.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkTLazy.h"
#include "src/gpu/GrColor.h"
#include "tests/Test.h"

View File

@ -135,38 +135,30 @@ bool BipmapToBase64DataURI(const SkBitmap& bitmap, SkString* dst) {
return true;
}
using AccessPixelFn = const float*(const char* floatBuffer, int x, int y);
bool compare_pixels(int width, int height,
const char* floatA, std::function<AccessPixelFn>& atA,
const char* floatB, std::function<AccessPixelFn>& atB,
const float tolRGBA[4], std::function<ComparePixmapsErrorReporter>& error) {
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
const float* rgbaA = atA(floatA, x, y);
const float* rgbaB = atB(floatB, x, y);
float diffs[4];
bool bad = false;
for (int i = 0; i < 4; ++i) {
diffs[i] = rgbaB[i] - rgbaA[i];
if (std::abs(diffs[i]) > std::abs(tolRGBA[i])) {
bad = true;
}
}
if (bad) {
error(x, y, diffs);
return false;
}
static bool compare_colors(int x, int y,
const float rgbaA[],
const float rgbaB[],
const float tolRGBA[4],
std::function<ComparePixmapsErrorReporter>& error) {
float diffs[4];
bool bad = false;
for (int i = 0; i < 4; ++i) {
diffs[i] = rgbaB[i] - rgbaA[i];
if (std::abs(diffs[i]) > std::abs(tolRGBA[i])) {
bad = true;
}
}
if (bad) {
error(x, y, diffs);
return false;
}
return true;
}
bool ComparePixels(const GrImageInfo& infoA, const char* a, size_t rowBytesA,
const GrImageInfo& infoB, const char* b, size_t rowBytesB,
const float tolRGBA[4], std::function<ComparePixmapsErrorReporter>& error) {
if (infoA.width() != infoB.width() || infoA.height() != infoB.height()) {
if (infoA.dimensions() != infoB.dimensions()) {
static constexpr float kDummyDiffs[4] = {};
error(-1, -1, kDummyDiffs);
return false;
@ -186,24 +178,31 @@ bool ComparePixels(const GrImageInfo& infoA, const char* a, size_t rowBytesA,
} else {
floatCS = SkColorSpace::MakeSRGBLinear();
}
GrImageInfo floatInfo(GrColorType::kRGBA_F32, floatAlphaType, std::move(floatCS),
infoA.width(), infoA.height());
GrImageInfo floatInfo(GrColorType::kRGBA_F32,
floatAlphaType,
std::move(floatCS),
infoA.dimensions());
size_t floatBpp = GrColorTypeBytesPerPixel(GrColorType::kRGBA_F32);
size_t floatRowBytes = floatBpp * infoA.width();
std::unique_ptr<char[]> floatA(new char[floatRowBytes * infoA.height()]);
std::unique_ptr<char[]> floatB(new char[floatRowBytes * infoA.height()]);
SkAssertResult(GrConvertPixels(floatInfo, floatA.get(), floatRowBytes, infoA, a, rowBytesA));
SkAssertResult(GrConvertPixels(floatInfo, floatB.get(), floatRowBytes, infoB, b, rowBytesB));
GrPixmap floatA = GrPixmap::Allocate(floatInfo);
GrPixmap floatB = GrPixmap::Allocate(floatInfo);
SkAssertResult(GrConvertPixels(floatA, GrCPixmap(infoA, a, rowBytesA)));
SkAssertResult(GrConvertPixels(floatB, GrCPixmap(infoB, b, rowBytesB)));
auto at = std::function<AccessPixelFn>(
[floatBpp, floatRowBytes](const char* floatBuffer, int x, int y) {
return reinterpret_cast<const float*>(floatBuffer + y * floatRowBytes + x * floatBpp);
});
SkASSERT(floatA.rowBytes() == floatB.rowBytes());
auto at = [rb = floatA.rowBytes()](const void* base, int x, int y) {
return SkTAddOffset<const float>(base, y*rb + x*sizeof(float)*4);
};
return compare_pixels(infoA.width(), infoA.height(),
floatA.get(), at, floatB.get(), at,
tolRGBA, error);
for (int y = 0; y < floatA.height(); ++y) {
for (int x = 0; x < floatA.width(); ++x) {
const float* rgbaA = at(floatA.addr(), x, y);
const float* rgbaB = at(floatB.addr(), x, y);
if (!compare_colors(x, y, rgbaA, rgbaB, tolRGBA, error)) {
return false;
}
}
}
return true;
}
bool ComparePixels(const SkPixmap& a, const SkPixmap& b, const float tolRGBA[4],
@ -213,45 +212,44 @@ bool ComparePixels(const SkPixmap& a, const SkPixmap& b, const float tolRGBA[4],
tolRGBA, error);
}
bool CheckSolidPixels(const SkColor4f& col, const SkPixmap& pixmap,
const float tolRGBA[4], std::function<ComparePixmapsErrorReporter>& error) {
bool CheckSolidPixels(const SkColor4f& col,
const SkPixmap& pixmap,
const float tolRGBA[4],
std::function<ComparePixmapsErrorReporter>& error) {
size_t floatBpp = GrColorTypeBytesPerPixel(GrColorType::kRGBA_F32);
std::unique_ptr<char[]> floatA(new char[floatBpp]);
// First convert 'col' to be compatible with 'pixmap'
GrPixmap colorPixmap;
{
sk_sp<SkColorSpace> srcCS = SkColorSpace::MakeSRGBLinear();
GrImageInfo srcInfo(GrColorType::kRGBA_F32, kUnpremul_SkAlphaType, std::move(srcCS), 1, 1);
GrImageInfo dstInfo(GrColorType::kRGBA_F32, pixmap.alphaType(), pixmap.refColorSpace(), 1, 1);
SkAssertResult(GrConvertPixels(dstInfo, floatA.get(), floatBpp, srcInfo,
col.vec(), floatBpp));
GrImageInfo srcInfo(GrColorType::kRGBA_F32,
kUnpremul_SkAlphaType,
std::move(srcCS),
{1, 1});
GrCPixmap srcPixmap(srcInfo, col.vec(), floatBpp);
GrImageInfo dstInfo =
srcInfo.makeAlphaType(pixmap.alphaType()).makeColorSpace(pixmap.refColorSpace());
colorPixmap = GrPixmap::Allocate(dstInfo);
SkAssertResult(GrConvertPixels(colorPixmap, srcPixmap));
}
size_t floatRowBytes = floatBpp * pixmap.width();
std::unique_ptr<char[]> floatB(new char[floatRowBytes * pixmap.height()]);
// Then convert 'pixmap' to RGBA_F32
{
GrImageInfo dstInfo(GrColorType::kRGBA_F32, pixmap.alphaType(), pixmap.refColorSpace(),
pixmap.width(), pixmap.height());
GrPixmap f32Pixmap = GrPixmap::Allocate(pixmap.info().makeColorType(kRGBA_F32_SkColorType));
SkAssertResult(GrConvertPixels(f32Pixmap, pixmap));
SkAssertResult(GrConvertPixels(dstInfo, floatB.get(), floatRowBytes, pixmap.info(),
pixmap.addr(), pixmap.rowBytes()));
for (int y = 0; y < f32Pixmap.height(); ++y) {
for (int x = 0; x < f32Pixmap.width(); ++x) {
auto rgbaA = SkTAddOffset<const float>(f32Pixmap.addr(),
f32Pixmap.rowBytes()*y + floatBpp*x);
auto rgbaB = static_cast<const float*>(colorPixmap.addr());
if (!compare_colors(x, y, rgbaA, rgbaB, tolRGBA, error)) {
return false;
}
}
}
auto atA = std::function<AccessPixelFn>(
[](const char* floatBuffer, int /* x */, int /* y */) {
return reinterpret_cast<const float*>(floatBuffer);
});
auto atB = std::function<AccessPixelFn>(
[floatBpp, floatRowBytes](const char* floatBuffer, int x, int y) {
return reinterpret_cast<const float*>(floatBuffer + y * floatRowBytes + x * floatBpp);
});
return compare_pixels(pixmap.width(), pixmap.height(), floatA.get(), atA, floatB.get(), atB,
tolRGBA, error);
return true;
}
void CheckSingleThreadedProxyRefs(skiatest::Reporter* reporter,

View File

@ -42,7 +42,8 @@ void fill_transfer_data(int left, int top, int width, int height, int bufferWidt
uint32_t srcPixel = GrColorPackRGBA(r, g, 0xff - r, 0xff - g);
GrImageInfo srcInfo(GrColorType::kRGBA_8888, kUnpremul_SkAlphaType, nullptr, 1, 1);
GrImageInfo dstInfo(dstType, kUnpremul_SkAlphaType, nullptr, 1, 1);
GrConvertPixels(dstInfo, dstLocation(i, j), dstBpp, srcInfo, &srcPixel, 4);
GrConvertPixels(GrPixmap(dstInfo, dstLocation(i, j), dstBpp),
GrPixmap(srcInfo, &srcPixel, 4));
}
}
}
@ -88,8 +89,8 @@ bool read_pixels_from_texture(GrTexture* texture, GrColorType colorType, char* d
GrImageInfo tmpInfo(supportedRead.fColorType, kUnpremul_SkAlphaType, nullptr, w, h);
GrImageInfo dstInfo(colorType, kUnpremul_SkAlphaType, nullptr, w, h);
determine_tolerances(tmpInfo.colorType(), dstInfo.colorType(), tolerances);
return GrConvertPixels(dstInfo, dst, rowBytes, tmpInfo, tmpPixels.get(), tmpRowBytes,
false);
return GrConvertPixels(GrPixmap(dstInfo, dst, rowBytes),
GrPixmap(tmpInfo, tmpPixels.get(), tmpRowBytes));
}
return gpu->readPixels(texture, 0, 0, w, h, colorType, supportedRead.fColorType, dst, rowBytes);
}

View File

@ -5,10 +5,12 @@
* found in the LICENSE file.
*/
#include "tools/flags/CommonFlagsConfig.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkSurfaceProps.h"
#include "include/private/SkTHash.h"
#include "src/core/SkColorSpacePriv.h"
#include "tools/flags/CommonFlagsConfig.h"
#include <stdlib.h>

View File

@ -52,7 +52,7 @@ GrTextureProxy* GetTextureImageProxy(SkImage* image, GrRecordingContext* rContex
GrSurfaceProxyView MakeTextureProxyViewFromData(GrDirectContext* dContext,
GrRenderable renderable,
GrSurfaceOrigin origin,
GrPixmap pixmap) {
GrCPixmap pixmap) {
if (dContext->abandoned()) {
return {};
}

View File

@ -15,7 +15,7 @@
class GrDirectContext;
class GrProgramInfo;
class GrPixmap;
class GrCPixmap;
namespace sk_gpu_test {
@ -26,7 +26,7 @@ GrTextureProxy* GetTextureImageProxy(SkImage*, GrRecordingContext*);
GrSurfaceProxyView MakeTextureProxyViewFromData(GrDirectContext*,
GrRenderable,
GrSurfaceOrigin,
GrPixmap pixmap);
GrCPixmap pixmap);
GrProgramInfo* CreateProgramInfo(const GrCaps*,
SkArenaAlloc*,

View File

@ -5,6 +5,8 @@
* found in the LICENSE file.
*/
#include "tools/gpu/gl/angle/GLTestContext_angle.h"
#include "include/core/SkTime.h"
#include "include/gpu/gl/GrGLAssembleInterface.h"
#include "include/gpu/gl/GrGLInterface.h"
@ -12,9 +14,10 @@
#include "src/gpu/gl/GrGLDefines.h"
#include "src/gpu/gl/GrGLUtil.h"
#include "src/ports/SkOSLibrary.h"
#include "tools/gpu/gl/angle/GLTestContext_angle.h"
#include "third_party/externals/angle2/include/platform/Platform.h"
#include <vector>
#define EGL_EGL_PROTOTYPES 1
#include <EGL/egl.h>
#include <EGL/eglext.h>