Reland "Make GrDirectContext::updateBackendTexture handle pixmaps with non-type row bytes."
This is a reland of 07d8c0d11cae593c46b2fbc0507b8c07cff9000f
Original change's description:
> Make GrDirectContext::updateBackendTexture handle pixmaps with non-type row bytes.
>
> Some GL contexts don't support GL_UNPACK_ROW_LENGTH and we must
> copy the src data to a pixmap with tight row bytes.
>
> Bug: chromium:1170392
>
> Change-Id: I4590f20dbc80cb792f30f0059536716cf106f6c3
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/361717
> Reviewed-by: Robert Phillips <robertphillips@google.com>
> Commit-Queue: Brian Salomon <bsalomon@google.com>
Bug: chromium:1170392
Change-Id: I6fb759c35f86d816b16694b00edaa1116a446d15
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/363099
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/tests/BackendAllocationTest.cpp b/tests/BackendAllocationTest.cpp
index fbb78ea..f34d124 100644
--- a/tests/BackendAllocationTest.cpp
+++ b/tests/BackendAllocationTest.cpp
@@ -425,16 +425,31 @@
}
}
-static int make_pixmaps(SkColorType skColorType, GrMipmapped mipMapped,
- const SkColor4f colors[6], SkAutoPixmapStorage pixmaps[6]) {
+static int make_pixmaps(SkColorType skColorType,
+ GrMipmapped mipmapped,
+ const SkColor4f colors[6],
+ SkPixmap pixmaps[6],
+ std::unique_ptr<char[]>* mem) {
int levelSize = 32;
- int numMipLevels = mipMapped == GrMipmapped::kYes ? 6 : 1;
+ int numMipLevels = mipmapped == GrMipmapped::kYes ? 6 : 1;
+ size_t size = 0;
+ SkImageInfo ii[6];
+ size_t rowBytes[6];
for (int level = 0; level < numMipLevels; ++level) {
- SkImageInfo ii = SkImageInfo::Make(levelSize,
- levelSize,
- skColorType,
- kUnpremul_SkAlphaType);
- pixmaps[level].alloc(ii);
+ ii[level] = SkImageInfo::Make(levelSize, levelSize, skColorType, kUnpremul_SkAlphaType);
+ rowBytes[level] = ii[level].minRowBytes();
+ // Make sure we test row bytes that aren't tight.
+ if (!(level % 2)) {
+ rowBytes[level] += (level + 1)*SkColorTypeBytesPerPixel(ii[level].colorType());
+ }
+ size += rowBytes[level]*ii[level].height();
+ levelSize /= 2;
+ }
+ mem->reset(new char[size]);
+ char* addr = mem->get();
+ for (int level = 0; level < numMipLevels; ++level) {
+ pixmaps[level].reset(ii[level], addr, rowBytes[level]);
+ addr += rowBytes[level]*ii[level].height();
pixmaps[level].erase(colors[level]);
levelSize /= 2;
}
@@ -451,9 +466,10 @@
GrRenderable)> create,
SkColorType skColorType,
GrSurfaceOrigin origin,
- GrMipmapped mipMapped,
+ GrMipmapped mipmapped,
GrRenderable renderable) {
- SkAutoPixmapStorage pixmapMem[6];
+ SkPixmap pixmaps[6];
+ std::unique_ptr<char[]> memForPixmaps;
SkColor4f colors[6] = {
{ 1.0f, 0.0f, 0.0f, 1.0f }, // R
{ 0.0f, 1.0f, 0.0f, 0.9f }, // G
@@ -463,15 +479,9 @@
{ 1.0f, 1.0f, 0.0f, 0.2f }, // Y
};
- int numMipLevels = make_pixmaps(skColorType, mipMapped, colors, pixmapMem);
+ int numMipLevels = make_pixmaps(skColorType, mipmapped, colors, pixmaps, &memForPixmaps);
SkASSERT(numMipLevels);
- // TODO: this is tedious. Should we pass in an array of SkBitmaps instead?
- SkPixmap pixmaps[6];
- for (int i = 0; i < numMipLevels; ++i) {
- pixmaps[i].reset(pixmapMem[i].info(), pixmapMem[i].addr(), pixmapMem[i].rowBytes());
- }
-
sk_sp<ManagedBackendTexture> mbet = create(dContext, pixmaps, numMipLevels, origin, renderable);
if (!mbet) {
// errors here should be reported by the test_wrapping test
@@ -485,7 +495,7 @@
auto checkBackendTexture = [&](SkColor4f colors[6]) {
GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
- if (mipMapped == GrMipmapped::kYes) {
+ if (mipmapped == GrMipmapped::kYes) {
SkColor4f expectedColors[6] = {
get_expected_color(colors[0], grColorType),
get_expected_color(colors[1], grColorType),
@@ -514,10 +524,7 @@
{0.0f, 1.0f, 1.0f, 0.5f}, // C
{1.0f, 0.0f, 1.0f, 0.3f}, // M
};
- make_pixmaps(skColorType, mipMapped, colorsNew, pixmapMem);
- for (int i = 0; i < numMipLevels; ++i) {
- pixmaps[i].reset(pixmapMem[i].info(), pixmapMem[i].addr(), pixmapMem[i].rowBytes());
- }
+ make_pixmaps(skColorType, mipmapped, colorsNew, pixmaps, &memForPixmaps);
// Upload new data and make sure everything still works
dContext->updateBackendTexture(mbet->texture(),
@@ -560,7 +567,8 @@
}
///////////////////////////////////////////////////////////////////////////////
-DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ColorTypeBackendAllocationTest, reporter, ctxInfo) {
+void color_type_backend_allocation_test(const sk_gpu_test::ContextInfo& ctxInfo,
+ skiatest::Reporter* reporter) {
auto context = ctxInfo.directContext();
const GrCaps* caps = context->priv().caps();
@@ -718,6 +726,31 @@
}
}
+DEF_GPUTEST(ColorTypeBackendAllocationTest, reporter, options) {
+ for (int t = 0; t < sk_gpu_test::GrContextFactory::kContextTypeCnt; ++t) {
+ auto type = static_cast<sk_gpu_test::GrContextFactory::ContextType>(t);
+ if (!sk_gpu_test::GrContextFactory::IsRenderingContext(type)) {
+ continue;
+ }
+ sk_gpu_test::GrContextFactory factory(options);
+ sk_gpu_test::ContextInfo info = factory.getContextInfo(type);
+ if (!info.directContext()) {
+ continue;
+ }
+ color_type_backend_allocation_test(info, reporter);
+ // The GL backend must support contexts that don't allow GL_UNPACK_ROW_LENGTH. Other
+ // backends are not required to work with this cap disabled.
+ if (info.directContext()->priv().caps()->writePixelsRowBytesSupport() &&
+ info.directContext()->backend() == GrBackendApi::kOpenGL) {
+ GrContextOptions overrideOptions = options;
+ overrideOptions.fDisallowWritePixelRowBytes = true;
+ sk_gpu_test::GrContextFactory overrideFactory(overrideOptions);
+ info = overrideFactory.getContextInfo(type);
+ color_type_backend_allocation_test(info, reporter);
+ }
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
#ifdef SK_GL