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/src/gpu/GrDirectContext.cpp b/src/gpu/GrDirectContext.cpp
index ab5c6cf..6e393e7 100644
--- a/src/gpu/GrDirectContext.cpp
+++ b/src/gpu/GrDirectContext.cpp
@@ -505,26 +505,34 @@
const GrBackendTexture& backendTexture,
GrSurfaceOrigin textureOrigin,
sk_sp<GrRefCntedCallback> finishedCallback) {
+ bool flip = textureOrigin == kBottomLeft_GrSurfaceOrigin;
+ bool mustBeTight = !gpu->caps()->writePixelsRowBytesSupport();
+
+ size_t size = 0;
+ for (int i = 0; i < numLevels; ++i) {
+ size_t minRowBytes = srcData[i].info().minRowBytes();
+ if (flip || (mustBeTight && srcData[i].rowBytes() != minRowBytes)) {
+ size += minRowBytes * srcData[i].height();
+ }
+ }
+
std::unique_ptr<char[]> tempStorage;
- SkAutoSTArray<15, GrPixmap> tempPixmaps(numLevels);
- if (textureOrigin == kBottomLeft_GrSurfaceOrigin) {
- size_t size = 0;
- for (int i = 0; i < numLevels; ++i) {
- size += srcData[i].info().minRowBytes()*srcData[i].height();
- }
+ if (size) {
tempStorage.reset(new char[size]);
- size = 0;
- for (int i = 0; i < numLevels; ++i) {
- size_t tempRB = srcData[i].info().minRowBytes();
- tempPixmaps[i] = {srcData[i].info(), tempStorage.get() + size, tempRB};
- SkAssertResult(GrConvertPixels(tempPixmaps[i], srcData[i], /*flip*/ true));
- size += tempRB*srcData[i].height();
- }
- } else {
- for (int i = 0; i < numLevels; ++i) {
+ }
+ size = 0;
+ SkAutoSTArray<15, GrPixmap> tempPixmaps(numLevels);
+ for (int i = 0; i < numLevels; ++i) {
+ size_t minRowBytes = srcData[i].info().minRowBytes();
+ if (flip || (mustBeTight && srcData[i].rowBytes() != minRowBytes)) {
+ tempPixmaps[i] = {srcData[i].info(), tempStorage.get() + size, minRowBytes};
+ SkAssertResult(GrConvertPixels(tempPixmaps[i], srcData[i], flip));
+ size += minRowBytes*srcData[i].height();
+ } else {
tempPixmaps[i] = srcData[i];
}
}
+
GrGpu::BackendTextureData data(tempPixmaps.get());
return gpu->updateBackendTexture(backendTexture, std::move(finishedCallback), &data);
}