Make GrGpu pixel ops functions take SkIRect instead of LTRB params.
Change-Id: Ic4a8a32a434485b84284decbcc5a8f898197169a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/408359
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrDeferredProxyUploader.h b/src/gpu/GrDeferredProxyUploader.h
index 33e62a5..34f077c 100644
--- a/src/gpu/GrDeferredProxyUploader.h
+++ b/src/gpu/GrDeferredProxyUploader.h
@@ -58,8 +58,11 @@
// If the worker thread was unable to allocate pixels, this check will fail, and we'll
// end up drawing with an uninitialized mask texture, but at least we won't crash.
if (this->fPixels.addr()) {
- writePixelsFn(proxy, 0, 0, this->fPixels.width(), this->fPixels.height(),
- pixelColorType, this->fPixels.addr(), this->fPixels.rowBytes());
+ writePixelsFn(proxy,
+ SkIRect::MakeSize(fPixels.dimensions()),
+ pixelColorType,
+ this->fPixels.addr(),
+ this->fPixels.rowBytes());
}
// Upload has finished, so tell the proxy to release this GrDeferredProxyUploader
proxy->texPriv().resetDeferredUploader();
diff --git a/src/gpu/GrDeferredUpload.h b/src/gpu/GrDeferredUpload.h
index 946787b..8c4f668 100644
--- a/src/gpu/GrDeferredUpload.h
+++ b/src/gpu/GrDeferredUpload.h
@@ -115,9 +115,11 @@
* Passed to a deferred upload when it is executed, this method allows the deferred upload to
* actually write its pixel data into a texture.
*/
-using GrDeferredTextureUploadWritePixelsFn =
- std::function<bool(GrTextureProxy*, int left, int top, int width, int height,
- GrColorType srcColorType, const void* buffer, size_t rowBytes)>;
+using GrDeferredTextureUploadWritePixelsFn = std::function<bool(GrTextureProxy*,
+ SkIRect,
+ GrColorType srcColorType,
+ const void*,
+ size_t rowBytes)>;
/**
* A deferred texture upload is simply a std::function that takes a
diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp
index c562c55..253043e 100644
--- a/src/gpu/GrDrawOpAtlas.cpp
+++ b/src/gpu/GrDrawOpAtlas.cpp
@@ -176,8 +176,11 @@
dataPtr += rowBytes * fDirtyRect.fTop;
dataPtr += fBytesPerPixel * fDirtyRect.fLeft;
- writePixels(proxy, fOffset.fX + fDirtyRect.fLeft, fOffset.fY + fDirtyRect.fTop,
- fDirtyRect.width(), fDirtyRect.height(), fColorType, dataPtr, rowBytes);
+ writePixels(proxy,
+ fDirtyRect.makeOffset(fOffset.fX, fOffset.fY),
+ fColorType,
+ dataPtr,
+ rowBytes);
fDirtyRect.setEmpty();
SkDEBUGCODE(fDirty = false;)
}
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 32d5f60..8afc77d 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -207,8 +207,12 @@
// Currently if level 0 does not have pixels then no other level may, as enforced by
// validate_texel_levels.
if (texelLevelCount && texels[0].fPixels) {
- if (!this->writePixels(tex.get(), 0, 0, dimensions.fWidth, dimensions.fHeight,
- textureColorType, srcColorType, texels, texelLevelCount)) {
+ if (!this->writePixels(tex.get(),
+ SkIRect::MakeSize(dimensions),
+ textureColorType,
+ srcColorType,
+ texels,
+ texelLevelCount)) {
return nullptr;
}
// Currently if level[1] of mip map has pixel data then so must all other levels.
@@ -379,21 +383,22 @@
return this->onCopySurface(dst, src, srcRect, dstPoint);
}
-bool GrGpu::readPixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
+bool GrGpu::readPixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType dstColorType,
+ void* buffer,
size_t rowBytes) {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
SkASSERT(surface);
SkASSERT(!surface->framebufferOnly());
SkASSERT(this->caps()->isFormatTexturable(surface->backendFormat()));
- auto subRect = SkIRect::MakeXYWH(left, top, width, height);
- auto bounds = SkIRect::MakeWH(surface->width(), surface->height());
- if (!bounds.contains(subRect)) {
+ if (!SkIRect::MakeSize(surface->dimensions()).contains(rect)) {
return false;
}
- size_t minRowBytes = SkToSizeT(GrColorTypeBytesPerPixel(dstColorType) * width);
+ size_t minRowBytes = SkToSizeT(GrColorTypeBytesPerPixel(dstColorType) * rect.width());
if (!this->caps()->readPixelsRowBytesSupport()) {
if (rowBytes != minRowBytes) {
return false;
@@ -409,13 +414,16 @@
this->handleDirtyContext();
- return this->onReadPixels(surface, left, top, width, height, surfaceColorType, dstColorType,
- buffer, rowBytes);
+ return this->onReadPixels(surface, rect, surfaceColorType, dstColorType, buffer, rowBytes);
}
-bool GrGpu::writePixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType srcColorType,
- const GrMipLevel texels[], int mipLevelCount, bool prepForTexSampling) {
+bool GrGpu::writePixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType srcColorType,
+ const GrMipLevel texels[],
+ int mipLevelCount,
+ bool prepForTexSampling) {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
ATRACE_ANDROID_FRAMEWORK_ALWAYS("Texture upload(%u) %ix%i",
surface->uniqueID().asUInt(), width, height);
@@ -430,25 +438,26 @@
return false;
} else if (mipLevelCount == 1) {
// We require that if we are not mipped, then the write region is contained in the surface
- auto subRect = SkIRect::MakeXYWH(left, top, width, height);
- auto bounds = SkIRect::MakeWH(surface->width(), surface->height());
- if (!bounds.contains(subRect)) {
+ if (!SkIRect::MakeSize(surface->dimensions()).contains(rect)) {
return false;
}
- } else if (0 != left || 0 != top || width != surface->width() || height != surface->height()) {
+ } else if (rect != SkIRect::MakeSize(surface->dimensions())) {
// We require that if the texels are mipped, than the write region is the entire surface
return false;
}
- if (!validate_texel_levels({width, height}, srcColorType, texels, mipLevelCount,
- this->caps())) {
+ if (!validate_texel_levels(rect.size(), srcColorType, texels, mipLevelCount, this->caps())) {
return false;
}
this->handleDirtyContext();
- if (this->onWritePixels(surface, left, top, width, height, surfaceColorType, srcColorType,
- texels, mipLevelCount, prepForTexSampling)) {
- SkIRect rect = SkIRect::MakeXYWH(left, top, width, height);
+ if (this->onWritePixels(surface,
+ rect,
+ surfaceColorType,
+ srcColorType,
+ texels,
+ mipLevelCount,
+ prepForTexSampling)) {
this->didWriteToSurface(surface, kTopLeft_GrSurfaceOrigin, &rect, mipLevelCount);
fStats.incTextureUploads();
return true;
@@ -456,9 +465,13 @@
return false;
}
-bool GrGpu::transferPixelsTo(GrTexture* texture, int left, int top, int width, int height,
- GrColorType textureColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset, size_t rowBytes) {
+bool GrGpu::transferPixelsTo(GrTexture* texture,
+ SkIRect rect,
+ GrColorType textureColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer> transferBuffer,
+ size_t offset,
+ size_t rowBytes) {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
SkASSERT(texture);
SkASSERT(transferBuffer);
@@ -468,30 +481,32 @@
}
// We require that the write region is contained in the texture
- SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
- SkIRect bounds = SkIRect::MakeWH(texture->width(), texture->height());
- if (!bounds.contains(subRect)) {
+ if (!SkIRect::MakeSize(texture->dimensions()).contains(rect)) {
return false;
}
size_t bpp = GrColorTypeBytesPerPixel(bufferColorType);
if (this->caps()->writePixelsRowBytesSupport()) {
- if (rowBytes < SkToSizeT(bpp * width)) {
+ if (rowBytes < SkToSizeT(bpp*rect.width())) {
return false;
}
if (rowBytes % bpp) {
return false;
}
} else {
- if (rowBytes != SkToSizeT(bpp * width)) {
+ if (rowBytes != SkToSizeT(bpp*rect.width())) {
return false;
}
}
this->handleDirtyContext();
- if (this->onTransferPixelsTo(texture, left, top, width, height, textureColorType,
- bufferColorType, std::move(transferBuffer), offset, rowBytes)) {
- SkIRect rect = SkIRect::MakeXYWH(left, top, width, height);
+ if (this->onTransferPixelsTo(texture,
+ rect,
+ textureColorType,
+ bufferColorType,
+ std::move(transferBuffer),
+ offset,
+ rowBytes)) {
this->didWriteToSurface(texture, kTopLeft_GrSurfaceOrigin, &rect);
fStats.incTransfersToTexture();
@@ -500,9 +515,12 @@
return false;
}
-bool GrGpu::transferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset) {
+bool GrGpu::transferPixelsFrom(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer> transferBuffer,
+ size_t offset) {
TRACE_EVENT0("skia.gpu", TRACE_FUNC);
SkASSERT(surface);
SkASSERT(transferBuffer);
@@ -516,15 +534,17 @@
#endif
// We require that the write region is contained in the texture
- SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
- SkIRect bounds = SkIRect::MakeWH(surface->width(), surface->height());
- if (!bounds.contains(subRect)) {
+ if (!SkIRect::MakeSize(surface->dimensions()).contains(rect)) {
return false;
}
this->handleDirtyContext();
- if (this->onTransferPixelsFrom(surface, left, top, width, height, surfaceColorType,
- bufferColorType, std::move(transferBuffer), offset)) {
+ if (this->onTransferPixelsFrom(surface,
+ rect,
+ surfaceColorType,
+ bufferColorType,
+ std::move(transferBuffer),
+ offset)) {
fStats.incTransfersFromSurface();
return true;
}
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 7a83519..fbe28a8 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -219,11 +219,8 @@
/**
* Reads a rectangle of pixels from a render target. No sRGB/linear conversions are performed.
*
- * @param surface The surface to read from
- * @param left left edge of the rectangle to read (inclusive)
- * @param top top edge of the rectangle to read (inclusive)
- * @param width width of rectangle to read in pixels.
- * @param height height of rectangle to read in pixels.
+ * @param surface the surface to read from
+ * @param rect the rectangle of pixels to read
* @param surfaceColorType the color type for this use of the surface.
* @param dstColorType the color type of the destination buffer.
* @param buffer memory to read the rectangle into.
@@ -236,18 +233,18 @@
* is not allowed for the format of the surface or if the rectangle
* read is not contained in the surface.
*/
- bool readPixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
+ bool readPixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType dstColorType,
+ void* buffer,
size_t rowBytes);
/**
* Updates the pixels in a rectangle of a surface. No sRGB/linear conversions are performed.
*
- * @param surface The surface to write to.
- * @param left left edge of the rectangle to write (inclusive)
- * @param top top edge of the rectangle to write (inclusive)
- * @param width width of rectangle to write in pixels.
- * @param height height of rectangle to write in pixels.
+ * @param surface the surface to write to.
+ * @param rect the rectangle of pixels to overwrite
* @param surfaceColorType the color type for this use of the surface.
* @param srcColorType the color type of the source buffer.
* @param texels array of mipmap levels containing texture data. Row bytes must be a
@@ -267,41 +264,55 @@
* the color type is not allowed for the format of the surface or
* if the rectangle written is not contained in the surface.
*/
- bool writePixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType srcColorType,
- const GrMipLevel texels[], int mipLevelCount, bool prepForTexSampling = false);
+ bool writePixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType srcColorType,
+ const GrMipLevel texels[],
+ int mipLevelCount,
+ bool prepForTexSampling = false);
/**
* Helper for the case of a single level.
*/
- bool writePixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType srcColorType, const void* buffer,
- size_t rowBytes, bool prepForTexSampling = false) {
+ bool writePixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType srcColorType,
+ const void* buffer,
+ size_t rowBytes,
+ bool prepForTexSampling = false) {
GrMipLevel mipLevel = {buffer, rowBytes, nullptr};
- return this->writePixels(surface, left, top, width, height, surfaceColorType, srcColorType,
- &mipLevel, 1, prepForTexSampling);
+ return this->writePixels(surface,
+ rect,
+ surfaceColorType,
+ srcColorType,
+ &mipLevel,
+ 1,
+ prepForTexSampling);
}
/**
* Updates the pixels in a rectangle of a texture using a buffer. If the texture is MIP mapped,
* the base level is written to.
*
- * @param texture The texture to write to.
- * @param left left edge of the rectangle to write (inclusive)
- * @param top top edge of the rectangle to write (inclusive)
- * @param width width of rectangle to write in pixels.
- * @param height height of rectangle to write in pixels.
+ * @param texture the texture to write to.
+ * @param rect the rectangle of pixels in the texture to overwrite
* @param textureColorType the color type for this use of the surface.
* @param bufferColorType the color type of the transfer buffer's pixel data
* @param transferBuffer GrBuffer to read pixels from (type must be "kXferCpuToGpu")
* @param offset offset from the start of the buffer
* @param rowBytes number of bytes between consecutive rows in the buffer. Must be a
- * multiple of bufferColorType's bytes-per-pixel. Must be tight to width
- * if !caps->writePixelsRowBytesSupport().
+ * multiple of bufferColorType's bytes-per-pixel. Must be tight to
+ * rect.width() if !caps->writePixelsRowBytesSupport().
*/
- bool transferPixelsTo(GrTexture* texture, int left, int top, int width, int height,
- GrColorType textureColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset, size_t rowBytes);
+ bool transferPixelsTo(GrTexture* texture,
+ SkIRect rect,
+ GrColorType textureColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer> transferBuffer,
+ size_t offset,
+ size_t rowBytes);
/**
* Reads the pixels from a rectangle of a surface into a buffer. Use
@@ -309,24 +320,24 @@
* the buffer offset alignment. If the surface is a MIP mapped texture, the base level is read.
*
* If successful the row bytes in the buffer is always:
- * GrColorTypeBytesPerPixel(bufferColorType) * width
+ * GrColorTypeBytesPerPixel(bufferColorType) * rect.width()
*
* Asserts that the caller has passed a properly aligned offset and that the buffer is
* large enough to hold the result
*
- * @param surface The surface to read from.
- * @param left left edge of the rectangle to read (inclusive)
- * @param top top edge of the rectangle to read (inclusive)
- * @param width width of rectangle to read in pixels.
- * @param height height of rectangle to read in pixels.
+ * @param surface the surface to read from.
+ * @param rect the rectangle of pixels to read
* @param surfaceColorType the color type for this use of the surface.
* @param bufferColorType the color type of the transfer buffer's pixel data
* @param transferBuffer GrBuffer to write pixels to (type must be "kXferGpuToCpu")
* @param offset offset from the start of the buffer
*/
- bool transferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset);
+ bool transferPixelsFrom(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer> transferBuffer,
+ size_t offset);
// Called to perform a surface to surface copy. Fallbacks to issuing a draw from the src to dst
// take place at higher levels and this function implement faster copy paths. The rect
@@ -716,24 +727,36 @@
GrAccessPattern, const void* data) = 0;
// overridden by backend-specific derived class to perform the surface read
- virtual bool onReadPixels(GrSurface*, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
+ virtual bool onReadPixels(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType dstColorType,
+ void*,
size_t rowBytes) = 0;
// overridden by backend-specific derived class to perform the surface write
- virtual bool onWritePixels(GrSurface*, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType srcColorType,
- const GrMipLevel texels[], int mipLevelCount,
+ virtual bool onWritePixels(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType srcColorType,
+ const GrMipLevel[],
+ int mipLevelCount,
bool prepForTexSampling) = 0;
// overridden by backend-specific derived class to perform the texture transfer
- virtual bool onTransferPixelsTo(GrTexture*, int left, int top, int width, int height,
- GrColorType textiueColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset,
+ virtual bool onTransferPixelsTo(GrTexture*,
+ SkIRect,
+ GrColorType textiueColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer> transferBuffer,
+ size_t offset,
size_t rowBytes) = 0;
+
// overridden by backend-specific derived class to perform the surface transfer
- virtual bool onTransferPixelsFrom(GrSurface*, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
+ virtual bool onTransferPixelsFrom(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
sk_sp<GrGpuBuffer> transferBuffer,
size_t offset) = 0;
diff --git a/src/gpu/GrOpFlushState.cpp b/src/gpu/GrOpFlushState.cpp
index 36f01be..67da4ab 100644
--- a/src/gpu/GrOpFlushState.cpp
+++ b/src/gpu/GrOpFlushState.cpp
@@ -100,24 +100,27 @@
void GrOpFlushState::doUpload(GrDeferredTextureUploadFn& upload,
bool shouldPrepareSurfaceForSampling) {
GrDeferredTextureUploadWritePixelsFn wp = [this, shouldPrepareSurfaceForSampling](
- GrTextureProxy* dstProxy, int left, int top, int width, int height,
- GrColorType colorType, const void* buffer, size_t rowBytes) {
+ GrTextureProxy* dstProxy,
+ SkIRect rect,
+ GrColorType colorType,
+ const void* buffer,
+ size_t rowBytes) {
GrSurface* dstSurface = dstProxy->peekSurface();
if (!fGpu->caps()->surfaceSupportsWritePixels(dstSurface)) {
return false;
}
GrCaps::SupportedWrite supportedWrite = fGpu->caps()->supportedWritePixelsColorType(
colorType, dstSurface->backendFormat(), colorType);
- size_t tightRB = width * GrColorTypeBytesPerPixel(supportedWrite.fColorType);
+ size_t tightRB = rect.width()*GrColorTypeBytesPerPixel(supportedWrite.fColorType);
SkASSERT(rowBytes >= tightRB);
std::unique_ptr<char[]> tmpPixels;
if (supportedWrite.fColorType != colorType ||
(!fGpu->caps()->writePixelsRowBytesSupport() && rowBytes != tightRB)) {
- tmpPixels.reset(new char[height * tightRB]);
+ tmpPixels.reset(new char[rect.height()*tightRB]);
// 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);
+ GrImageInfo srcInfo(colorType, kAT, nullptr, rect.size());
+ GrImageInfo tmpInfo(supportedWrite.fColorType, kAT, nullptr, rect.size());
if (!GrConvertPixels( GrPixmap(tmpInfo, tmpPixels.get(), tightRB ),
GrCPixmap(srcInfo, buffer, rowBytes))) {
return false;
@@ -125,8 +128,12 @@
rowBytes = tightRB;
buffer = tmpPixels.get();
}
- return this->fGpu->writePixels(dstSurface, left, top, width, height, colorType,
- supportedWrite.fColorType, buffer, rowBytes,
+ return this->fGpu->writePixels(dstSurface,
+ rect,
+ colorType,
+ supportedWrite.fColorType,
+ buffer,
+ rowBytes,
shouldPrepareSurfaceForSampling);
};
upload(wp);
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index 38738a5..4e52763 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -728,7 +728,11 @@
if (tempColorType == GrColorType::kUnknown) {
return nullptr;
}
- SkAssertResult(fGpu->writePixels(texture.get(), 0, 0, baseSize.fWidth, baseSize.fHeight,
- colorType, tempColorType, tmpTexels.get(), mipLevelCount));
+ SkAssertResult(fGpu->writePixels(texture.get(),
+ SkIRect::MakeSize(baseSize),
+ colorType,
+ tempColorType,
+ tmpTexels.get(),
+ mipLevelCount));
return texture;
}
diff --git a/src/gpu/GrSurfaceContext.cpp b/src/gpu/GrSurfaceContext.cpp
index 94682af..bc708d8 100644
--- a/src/gpu/GrSurfaceContext.cpp
+++ b/src/gpu/GrSurfaceContext.cpp
@@ -343,9 +343,12 @@
dContext->priv().flushSurface(srcProxy.get());
dContext->submit();
- if (!dContext->priv().getGpu()->readPixels(srcSurface, pt.fX, pt.fY, dst.width(), dst.height(),
+ if (!dContext->priv().getGpu()->readPixels(srcSurface,
+ SkIRect::MakePtSize(pt, dst.dimensions()),
this->colorInfo().colorType(),
- supportedRead.fColorType, readDst, readRB)) {
+ supportedRead.fColorType,
+ readDst,
+ readRB)) {
return false;
}
diff --git a/src/gpu/GrTransferFromRenderTask.cpp b/src/gpu/GrTransferFromRenderTask.cpp
index 4c1d848..0c679ed 100644
--- a/src/gpu/GrTransferFromRenderTask.cpp
+++ b/src/gpu/GrTransferFromRenderTask.cpp
@@ -24,7 +24,10 @@
if (!fSrcProxy->isInstantiated()) {
return false;
}
- return flushState->gpu()->transferPixelsFrom(
- fSrcProxy->peekSurface(), fSrcRect.fLeft, fSrcRect.fTop, fSrcRect.width(),
- fSrcRect.height(), fSurfaceColorType, fDstColorType, fDstBuffer, fDstOffset);
+ return flushState->gpu()->transferPixelsFrom(fSrcProxy->peekSurface(),
+ fSrcRect,
+ fSurfaceColorType,
+ fDstColorType,
+ fDstBuffer,
+ fDstOffset);
}
diff --git a/src/gpu/GrWritePixelsRenderTask.cpp b/src/gpu/GrWritePixelsRenderTask.cpp
index e8caeb2..1b2c37e 100644
--- a/src/gpu/GrWritePixelsRenderTask.cpp
+++ b/src/gpu/GrWritePixelsRenderTask.cpp
@@ -61,10 +61,7 @@
}
GrSurface* dstSurface = dstProxy->peekSurface();
return flushState->gpu()->writePixels(dstSurface,
- fRect.fLeft,
- fRect.fTop,
- fRect.width(),
- fRect.height(),
+ fRect,
fDstColorType,
fSrcColorType,
fLevels.get(),
diff --git a/src/gpu/d3d/GrD3DGpu.cpp b/src/gpu/d3d/GrD3DGpu.cpp
index 1567e91..5067b1b 100644
--- a/src/gpu/d3d/GrD3DGpu.cpp
+++ b/src/gpu/d3d/GrD3DGpu.cpp
@@ -556,8 +556,11 @@
this->resolveTexture(target, resolveRect.fLeft, resolveRect.fTop, rt, resolveRect);
}
-bool GrD3DGpu::onReadPixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
+bool GrD3DGpu::onReadPixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType dstColorType,
+ void* buffer,
size_t rowBytes) {
SkASSERT(surface);
@@ -588,8 +591,7 @@
GrGpuBufferType::kXferGpuToCpu,
kDynamic_GrAccessPattern);
- this->readOrTransferPixels(texResource, left, top, width, height, transferBuffer,
- placedFootprint);
+ this->readOrTransferPixels(texResource, rect, transferBuffer, placedFootprint);
this->submitDirectCommandList(SyncQueue::kForce);
// Copy back to CPU buffer
@@ -597,12 +599,16 @@
if (GrDxgiFormatBytesPerBlock(texResource->dxgiFormat()) != bpp) {
return false;
}
- size_t tightRowBytes = bpp * width;
+ size_t tightRowBytes = bpp * rect.width();
const void* mappedMemory = transferBuffer->map();
- SkRectMemcpy(buffer, rowBytes, mappedMemory, placedFootprint.Footprint.RowPitch,
- tightRowBytes, height);
+ SkRectMemcpy(buffer,
+ rowBytes,
+ mappedMemory,
+ placedFootprint.Footprint.RowPitch,
+ tightRowBytes,
+ rect.height());
transferBuffer->unmap();
@@ -610,7 +616,7 @@
}
void GrD3DGpu::readOrTransferPixels(GrD3DTextureResource* texResource,
- int left, int top, int width, int height,
+ SkIRect rect,
sk_sp<GrGpuBuffer> transferBuffer,
const D3D12_PLACED_SUBRESOURCE_FOOTPRINT& placedFootprint) {
// Set up src location and box
@@ -621,10 +627,10 @@
srcLocation.SubresourceIndex = 0;
D3D12_BOX srcBox = {};
- srcBox.left = left;
- srcBox.top = top;
- srcBox.right = left + width;
- srcBox.bottom = top + height;
+ srcBox.left = rect.left();
+ srcBox.top = rect.top();
+ srcBox.right = rect.right();
+ srcBox.bottom = rect.bottom();
srcBox.front = 0;
srcBox.back = 1;
@@ -643,9 +649,12 @@
&srcBox);
}
-bool GrD3DGpu::onWritePixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType srcColorType,
- const GrMipLevel texels[], int mipLevelCount,
+bool GrD3DGpu::onWritePixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType srcColorType,
+ const GrMipLevel texels[],
+ int mipLevelCount,
bool prepForTexSampling) {
GrD3DTexture* d3dTex = static_cast<GrD3DTexture*>(surface->asTexture());
if (!d3dTex) {
@@ -664,8 +673,7 @@
d3dTex->setResourceState(this, D3D12_RESOURCE_STATE_COPY_DEST);
SkASSERT(mipLevelCount <= d3dTex->maxMipmapLevel() + 1);
- success = this->uploadToTexture(d3dTex, left, top, width, height, srcColorType, texels,
- mipLevelCount);
+ success = this->uploadToTexture(d3dTex, rect, srcColorType, texels, mipLevelCount);
if (prepForTexSampling) {
d3dTex->setResourceState(this, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
@@ -674,18 +682,20 @@
return success;
}
-bool GrD3DGpu::uploadToTexture(GrD3DTexture* tex, int left, int top, int width, int height,
- GrColorType colorType, const GrMipLevel* texels, int mipLevelCount) {
+bool GrD3DGpu::uploadToTexture(GrD3DTexture* tex,
+ SkIRect rect,
+ GrColorType colorType,
+ const GrMipLevel* texels,
+ int mipLevelCount) {
SkASSERT(this->caps()->isFormatTexturable(tex->backendFormat()));
// The assumption is either that we have no mipmaps, or that our rect is the entire texture
- SkASSERT(1 == mipLevelCount ||
- (0 == left && 0 == top && width == tex->width() && height == tex->height()));
+ SkASSERT(mipLevelCount == 1 || rect == SkIRect::MakeSize(tex->dimensions()));
// We assume that if the texture has mip levels, we either upload to all the levels or just the
// first.
- SkASSERT(1 == mipLevelCount || mipLevelCount == (tex->maxMipmapLevel() + 1));
+ SkASSERT(mipLevelCount == 1 || mipLevelCount == (tex->maxMipmapLevel() + 1));
- if (width == 0 || height == 0) {
+ if (rect.isEmpty()) {
return false;
}
@@ -713,8 +723,8 @@
UINT64 combinedBufferSize;
// We reset the width and height in the description to match our subrectangle size
// so we don't end up allocating more space than we need.
- desc.Width = width;
- desc.Height = height;
+ desc.Width = rect.width();
+ desc.Height = rect.height();
fDevice->GetCopyableFootprints(&desc, 0, mipLevelCount, 0, placedFootprints.get(),
nullptr, nullptr, &combinedBufferSize);
size_t bpp = GrColorTypeBytesPerPixel(colorType);
@@ -728,8 +738,8 @@
char* bufferData = (char*)slice.fOffsetMapPtr;
- int currentWidth = width;
- int currentHeight = height;
+ int currentWidth = rect.width();
+ int currentHeight = rect.height();
int layerHeight = tex->height();
for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
@@ -757,8 +767,12 @@
}
ID3D12Resource* d3dBuffer = static_cast<GrD3DBuffer*>(slice.fBuffer)->d3dResource();
- fCurrentDirectCommandList->copyBufferToTexture(d3dBuffer, tex, mipLevelCount,
- placedFootprints.get(), left, top);
+ fCurrentDirectCommandList->copyBufferToTexture(d3dBuffer,
+ tex,
+ mipLevelCount,
+ placedFootprints.get(),
+ rect.left(),
+ rect.top());
if (mipLevelCount < (int)desc.MipLevels) {
tex->markMipmapsDirty();
@@ -767,9 +781,12 @@
return true;
}
-bool GrD3DGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t bufferOffset,
+bool GrD3DGpu::onTransferPixelsTo(GrTexture* texture,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer> transferBuffer,
+ size_t bufferOffset,
size_t rowBytes) {
if (!this->currentCommandList()) {
return false;
@@ -801,19 +818,15 @@
SkASSERT(GrDxgiFormatBytesPerBlock(format) == GrColorTypeBytesPerPixel(bufferColorType));
- SkDEBUGCODE(
- SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
- SkIRect bounds = SkIRect::MakeWH(texture->width(), texture->height());
- SkASSERT(bounds.contains(subRect));
- )
+ SkASSERT(SkIRect::MakeSize(texture->dimensions()).contains(rect));
// Set up copy region
D3D12_PLACED_SUBRESOURCE_FOOTPRINT placedFootprint = {};
ID3D12Resource* d3dResource = d3dTex->d3dResource();
SkASSERT(d3dResource);
D3D12_RESOURCE_DESC desc = d3dResource->GetDesc();
- desc.Width = width;
- desc.Height = height;
+ desc.Width = rect.width();
+ desc.Height = rect.height();
UINT64 totalBytes;
fDevice->GetCopyableFootprints(&desc, 0, 1, 0, &placedFootprint,
nullptr, nullptr, &totalBytes);
@@ -824,17 +837,24 @@
// Copy the buffer to the image.
ID3D12Resource* d3dBuffer = static_cast<GrD3DBuffer*>(transferBuffer.get())->d3dResource();
- fCurrentDirectCommandList->copyBufferToTexture(d3dBuffer, d3dTex, 1,
- &placedFootprint, left, top);
+ fCurrentDirectCommandList->copyBufferToTexture(d3dBuffer,
+ d3dTex,
+ 1,
+ &placedFootprint,
+ rect.left(),
+ rect.top());
this->currentCommandList()->addGrBuffer(std::move(transferBuffer));
d3dTex->markMipmapsDirty();
return true;
}
-bool GrD3DGpu::onTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset) {
+bool GrD3DGpu::onTransferPixelsFrom(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer> transferBuffer,
+ size_t offset) {
if (!this->currentCommandList()) {
return false;
}
@@ -866,16 +886,15 @@
SkASSERT(GrDxgiFormatBytesPerBlock(format) == GrColorTypeBytesPerPixel(bufferColorType));
D3D12_RESOURCE_DESC desc = texResource->d3dResource()->GetDesc();
- desc.Width = width;
- desc.Height = height;
+ desc.Width = rect.width();
+ desc.Height = rect.height();
D3D12_PLACED_SUBRESOURCE_FOOTPRINT placedFootprint;
UINT64 transferTotalBytes;
fDevice->GetCopyableFootprints(&desc, 0, 1, offset, &placedFootprint,
nullptr, nullptr, &transferTotalBytes);
SkASSERT(transferTotalBytes);
- this->readOrTransferPixels(texResource, left, top, width, height,
- transferBuffer, placedFootprint);
+ this->readOrTransferPixels(texResource, rect, transferBuffer, placedFootprint);
// TODO: It's not clear how to ensure the transfer is done before we read from the buffer,
// other than maybe doing a resource state transition.
diff --git a/src/gpu/d3d/GrD3DGpu.h b/src/gpu/d3d/GrD3DGpu.h
index d4a51bf..303eed1 100644
--- a/src/gpu/d3d/GrD3DGpu.h
+++ b/src/gpu/d3d/GrD3DGpu.h
@@ -165,22 +165,35 @@
sk_sp<GrGpuBuffer> onCreateBuffer(size_t sizeInBytes, GrGpuBufferType, GrAccessPattern,
const void*) override;
- bool onReadPixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
+ bool onReadPixels(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType dstColorType,
+ void*,
size_t rowBytes) override;
- bool onWritePixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType srcColorType,
- const GrMipLevel texels[], int mipLevelCount,
+ bool onWritePixels(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType srcColorType,
+ const GrMipLevel[],
+ int mipLevelCount,
bool prepForTexSampling) override;
- bool onTransferPixelsTo(GrTexture* texture, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset,
+ bool onTransferPixelsTo(GrTexture*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer>,
+ size_t offset,
size_t rowBytes) override;
- bool onTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset) override;
+
+ bool onTransferPixelsFrom(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer>,
+ size_t offset) override;
bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
const SkIPoint& dstPoint) override;
@@ -253,11 +266,14 @@
int mipLevelCount,
GrMipmapStatus);
- bool uploadToTexture(GrD3DTexture* tex, int left, int top, int width, int height,
- GrColorType colorType, const GrMipLevel* texels, int mipLevelCount);
+ bool uploadToTexture(GrD3DTexture* tex,
+ SkIRect rect,
+ GrColorType colorType,
+ const GrMipLevel texels[],
+ int mipLevelCount);
void readOrTransferPixels(GrD3DTextureResource* texResource,
- int left, int top, int width, int height,
+ SkIRect rect,
sk_sp<GrGpuBuffer> transferBuffer,
const D3D12_PLACED_SUBRESOURCE_FOOTPRINT& placedFootprint);
diff --git a/src/gpu/dawn/GrDawnGpu.cpp b/src/gpu/dawn/GrDawnGpu.cpp
index 537636b..44f3103 100644
--- a/src/gpu/dawn/GrDawnGpu.cpp
+++ b/src/gpu/dawn/GrDawnGpu.cpp
@@ -178,33 +178,41 @@
}
////////////////////////////////////////////////////////////////////////////////
-bool GrDawnGpu::onWritePixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType srcColorType,
- const GrMipLevel texels[], int mipLevelCount,
+bool GrDawnGpu::onWritePixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType srcColorType,
+ const GrMipLevel texels[],
+ int mipLevelCount,
bool prepForTexSampling) {
GrDawnTexture* texture = static_cast<GrDawnTexture*>(surface->asTexture());
if (!texture) {
return false;
}
- this->uploadTextureData(srcColorType, texels, mipLevelCount,
- SkIRect::MakeXYWH(left, top, width, height), texture->texture());
+ this->uploadTextureData(srcColorType, texels, mipLevelCount, rect, texture->texture());
if (mipLevelCount < texture->maxMipmapLevel() + 1) {
texture->markMipmapsDirty();
}
return true;
}
-bool GrDawnGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int width, int height,
- GrColorType textureColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t bufferOffset,
+bool GrDawnGpu::onTransferPixelsTo(GrTexture* texture,
+ SkIRect rect,
+ GrColorType textureColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer> transferBuffer,
+ size_t bufferOffset,
size_t rowBytes) {
SkASSERT(!"unimplemented");
return false;
}
-bool GrDawnGpu::onTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset) {
+bool GrDawnGpu::onTransferPixelsFrom(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer> transferBuffer,
+ size_t offset) {
SkASSERT(!"unimplemented");
return false;
}
@@ -603,8 +611,11 @@
*static_cast<bool*>(userdata) = true;
}
-bool GrDawnGpu::onReadPixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
+bool GrDawnGpu::onReadPixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType dstColorType,
+ void* buffer,
size_t rowBytes) {
wgpu::Texture tex = get_dawn_texture_from_surface(surface);
@@ -612,9 +623,9 @@
return false;
}
size_t origRowBytes = rowBytes;
- int origSizeInBytes = origRowBytes * height;
+ int origSizeInBytes = origRowBytes*rect.height();
rowBytes = GrDawnRoundRowBytes(rowBytes);
- int sizeInBytes = rowBytes * height;
+ int sizeInBytes = rowBytes*rect.height();
wgpu::BufferDescriptor desc;
desc.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::MapRead;
@@ -624,15 +635,15 @@
wgpu::ImageCopyTexture srcTexture;
srcTexture.texture = tex;
- srcTexture.origin = {(uint32_t) left, (uint32_t) top, 0};
+ srcTexture.origin = {(uint32_t) rect.left(), (uint32_t) rect.top(), 0};
wgpu::ImageCopyBuffer dstBuffer = {};
dstBuffer.buffer = buf;
dstBuffer.layout.offset = 0;
dstBuffer.layout.bytesPerRow = rowBytes;
- dstBuffer.layout.rowsPerImage = height;
+ dstBuffer.layout.rowsPerImage = rect.height();
- wgpu::Extent3D copySize = {(uint32_t) width, (uint32_t) height, 1};
+ wgpu::Extent3D copySize = {(uint32_t) rect.width(), (uint32_t) rect.height(), 1};
this->getCopyEncoder().CopyTextureToBuffer(&srcTexture, &dstBuffer, ©Size);
this->submitToGpu(true);
@@ -648,7 +659,7 @@
} else {
const char* src = static_cast<const char*>(readPixelsPtr);
char* dst = static_cast<char*>(buffer);
- for (int row = 0; row < height; row++) {
+ for (int row = 0; row < rect.height(); row++) {
memcpy(dst, src, origRowBytes);
dst += origRowBytes;
src += rowBytes;
diff --git a/src/gpu/dawn/GrDawnGpu.h b/src/gpu/dawn/GrDawnGpu.h
index 389a90b..4ceaf3f 100644
--- a/src/gpu/dawn/GrDawnGpu.h
+++ b/src/gpu/dawn/GrDawnGpu.h
@@ -160,23 +160,35 @@
sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType type, GrAccessPattern,
const void* data) override;
- bool onReadPixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
+ bool onReadPixels(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType dstColorType,
+ void*,
size_t rowBytes) override;
- bool onWritePixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType srcColorType,
- const GrMipLevel texels[], int mipLevelCount,
- bool prepForTexSampling) override;
+ bool onWritePixels(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType srcColorType,
+ const GrMipLevel[],
+ int mipLevelCount,
+ bool) override;
- bool onTransferPixelsTo(GrTexture*, int left, int top, int width, int height,
- GrColorType textureColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset,
+ bool onTransferPixelsTo(GrTexture*,
+ SkIRect,
+ GrColorType textureColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer>,
+ size_t offset,
size_t rowBytes) override;
- bool onTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset) override;
+ bool onTransferPixelsFrom(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer>,
+ size_t offset) override;
void onResolveRenderTarget(GrRenderTarget*, const SkIRect&) override {}
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 3dfab74..1129476 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -815,9 +815,12 @@
return true;
}
-bool GrGLGpu::onWritePixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType srcColorType,
- const GrMipLevel texels[], int mipLevelCount,
+bool GrGLGpu::onWritePixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType srcColorType,
+ const GrMipLevel texels[],
+ int mipLevelCount,
bool prepForTexSampling) {
auto glTex = static_cast<GrGLTexture*>(surface->asTexture());
@@ -845,15 +848,22 @@
}
SkASSERT(!GrGLFormatIsCompressed(glTex->format()));
- SkIRect dstRect = SkIRect::MakeXYWH(left, top, width, height);
- return this->uploadColorTypeTexData(glTex->format(), surfaceColorType, glTex->dimensions(),
- glTex->target(), dstRect, srcColorType, texels,
+ return this->uploadColorTypeTexData(glTex->format(),
+ surfaceColorType,
+ glTex->dimensions(),
+ glTex->target(),
+ rect,
+ srcColorType,
+ texels,
mipLevelCount);
}
-bool GrGLGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int width, int height,
- GrColorType textureColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset,
+bool GrGLGpu::onTransferPixelsTo(GrTexture* texture,
+ SkIRect rect,
+ GrColorType textureColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer> transferBuffer,
+ size_t offset,
size_t rowBytes) {
GrGLTexture* glTex = static_cast<GrGLTexture*>(texture);
@@ -865,9 +875,6 @@
}
static_assert(sizeof(int) == sizeof(int32_t), "");
- if (width <= 0 || height <= 0) {
- return false;
- }
this->bindTextureToScratchUnit(glTex->target(), glTex->textureID());
@@ -876,18 +883,11 @@
const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(transferBuffer.get());
this->bindBuffer(GrGpuBufferType::kXferCpuToGpu, glBuffer);
- SkDEBUGCODE(
- SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
- SkIRect bounds = SkIRect::MakeWH(texture->width(), texture->height());
- SkASSERT(bounds.contains(subRect));
- )
+ SkASSERT(SkIRect::MakeSize(texture->dimensions()).contains(rect));
size_t bpp = GrColorTypeBytesPerPixel(bufferColorType);
- const size_t trimRowBytes = width * bpp;
+ const size_t trimRowBytes = rect.width() * bpp;
const void* pixels = (void*)offset;
- if (width < 0 || height < 0) {
- return false;
- }
bool restoreGLRowLength = false;
if (trimRowBytes != rowBytes) {
@@ -910,10 +910,12 @@
GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, 1));
GL_CALL(TexSubImage2D(glTex->target(),
0,
- left, top,
- width,
- height,
- externalFormat, externalType,
+ rect.left(),
+ rect.top(),
+ rect.width(),
+ rect.height(),
+ externalFormat,
+ externalType,
pixels));
if (restoreGLRowLength) {
@@ -923,14 +925,21 @@
return true;
}
-bool GrGLGpu::onTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType dstColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset) {
+bool GrGLGpu::onTransferPixelsFrom(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType dstColorType,
+ sk_sp<GrGpuBuffer> transferBuffer,
+ size_t offset) {
auto* glBuffer = static_cast<GrGLBuffer*>(transferBuffer.get());
this->bindBuffer(GrGpuBufferType::kXferGpuToCpu, glBuffer);
auto offsetAsPtr = reinterpret_cast<void*>(offset);
- return this->readOrTransferPixelsFrom(surface, left, top, width, height, surfaceColorType,
- dstColorType, offsetAsPtr, width);
+ return this->readOrTransferPixelsFrom(surface,
+ rect,
+ surfaceColorType,
+ dstColorType,
+ offsetAsPtr,
+ rect.width());
}
void GrGLGpu::unbindXferBuffer(GrGpuBufferType type) {
@@ -2098,9 +2107,12 @@
fHWStencilSettings.invalidate();
}
-bool GrGLGpu::readOrTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType dstColorType,
- void* offsetOrPtr, int rowWidthInPixels) {
+bool GrGLGpu::readOrTransferPixelsFrom(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType dstColorType,
+ void* offsetOrPtr,
+ int rowWidthInPixels) {
SkASSERT(surface);
auto format = surface->backendFormat().asGLFormat();
@@ -2132,20 +2144,22 @@
fHWBoundRenderTargetUniqueID.makeInvalid();
}
- // the read rect is viewport-relative
- GrNativeRect readRect = {left, top, width, height};
-
// determine if GL can read using the passed rowBytes or if we need a scratch buffer.
- if (rowWidthInPixels != width) {
+ if (rowWidthInPixels != rect.width()) {
SkASSERT(this->glCaps().readPixelsRowBytesSupport());
GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, rowWidthInPixels));
}
GL_CALL(PixelStorei(GR_GL_PACK_ALIGNMENT, 1));
- GL_CALL(ReadPixels(readRect.fX, readRect.fY, readRect.fWidth, readRect.fHeight,
- externalFormat, externalType, offsetOrPtr));
+ GL_CALL(ReadPixels(rect.left(),
+ rect.top(),
+ rect.width(),
+ rect.height(),
+ externalFormat,
+ externalType,
+ offsetOrPtr));
- if (rowWidthInPixels != width) {
+ if (rowWidthInPixels != rect.width()) {
SkASSERT(this->glCaps().readPixelsRowBytesSupport());
GL_CALL(PixelStorei(GR_GL_PACK_ROW_LENGTH, 0));
}
@@ -2156,8 +2170,11 @@
return true;
}
-bool GrGLGpu::onReadPixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
+bool GrGLGpu::onReadPixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType dstColorType,
+ void* buffer,
size_t rowBytes) {
SkASSERT(surface);
@@ -2166,15 +2183,19 @@
// GL_PACK_ROW_LENGTH is in terms of pixels not bytes.
int rowPixelWidth;
- if (rowBytes == SkToSizeT(width * bytesPerPixel)) {
- rowPixelWidth = width;
+ if (rowBytes == SkToSizeT(rect.width()*bytesPerPixel)) {
+ rowPixelWidth = rect.width();
} else {
SkASSERT(!(rowBytes % bytesPerPixel));
rowPixelWidth = rowBytes / bytesPerPixel;
}
this->unbindXferBuffer(GrGpuBufferType::kXferGpuToCpu);
- return this->readOrTransferPixelsFrom(surface, left, top, width, height, surfaceColorType,
- dstColorType, buffer, rowPixelWidth);
+ return this->readOrTransferPixelsFrom(surface,
+ rect,
+ surfaceColorType,
+ dstColorType,
+ buffer,
+ rowPixelWidth);
}
GrOpsRenderPass* GrGLGpu::onGetOpsRenderPass(
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 79d8d3e..4bc691a 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -295,25 +295,42 @@
GrMipmapped,
GrGLTextureParameters::SamplerOverriddenState*);
- bool onReadPixels(GrSurface*, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
+ bool onReadPixels(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType dstColorType,
+ void*,
size_t rowBytes) override;
- bool onWritePixels(GrSurface*, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType srcColorType,
- const GrMipLevel texels[], int mipLevelCount,
+ bool onWritePixels(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType srcColorType,
+ const GrMipLevel[],
+ int mipLevelCount,
bool prepForTexSampling) override;
- bool onTransferPixelsTo(GrTexture*, int left, int top, int width, int height,
- GrColorType textureColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset,
+ bool onTransferPixelsTo(GrTexture*,
+ SkIRect,
+ GrColorType textureColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer>,
+ size_t offset,
size_t rowBytes) override;
- bool onTransferPixelsFrom(GrSurface*, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset) override;
- bool readOrTransferPixelsFrom(GrSurface*, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType dstColorType,
- void* offsetOrPtr, int rowWidthInPixels);
+
+ bool onTransferPixelsFrom(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer>,
+ size_t offset) override;
+
+ bool readOrTransferPixelsFrom(GrSurface*,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType dstColorType,
+ void* offsetOrPtr,
+ int rowWidthInPixels);
// Unbinds xfer buffers from GL for operations that don't need them.
// Before calling any variation of TexImage, TexSubImage, etc..., call this with
diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h
index a85d3d9..167632a 100644
--- a/src/gpu/mock/GrMockGpu.h
+++ b/src/gpu/mock/GrMockGpu.h
@@ -90,30 +90,44 @@
sk_sp<GrGpuBuffer> onCreateBuffer(size_t sizeInBytes, GrGpuBufferType, GrAccessPattern,
const void*) override;
- bool onReadPixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
+ bool onReadPixels(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType dstColorType,
+ void*,
size_t rowBytes) override {
return true;
}
- bool onWritePixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType srcColorType,
- const GrMipLevel texels[], int mipLevelCount,
+ bool onWritePixels(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType srcColorType,
+ const GrMipLevel[],
+ int mipLevelCount,
bool prepForTexSampling) override {
return true;
}
- bool onTransferPixelsTo(GrTexture* texture, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset,
+ bool onTransferPixelsTo(GrTexture*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer>,
+ size_t offset,
size_t rowBytes) override {
return true;
}
- bool onTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset) override {
+
+ bool onTransferPixelsFrom(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer>,
+ size_t offset) override {
return true;
}
+
bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
const SkIPoint& dstPoint) override {
return true;
diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h
index 6de43fe..1f691f0 100644
--- a/src/gpu/mtl/GrMtlGpu.h
+++ b/src/gpu/mtl/GrMtlGpu.h
@@ -179,21 +179,35 @@
sk_sp<GrGpuBuffer> onCreateBuffer(size_t, GrGpuBufferType, GrAccessPattern,
const void*) override;
- bool onReadPixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType, void* buffer,
+ bool onReadPixels(GrSurface* surface,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ void*,
size_t rowBytes) override;
- bool onWritePixels(GrSurface*, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- const GrMipLevel[], int mipLevelCount,
+ bool onWritePixels(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ const GrMipLevel[],
+ int mipLevelCount,
bool prepForTexSampling) override;
- bool onTransferPixelsTo(GrTexture*, int left, int top, int width, int height,
- GrColorType textureColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer>, size_t offset, size_t rowBytes) override;
- bool onTransferPixelsFrom(GrSurface*, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer>, size_t offset) override;
+ bool onTransferPixelsTo(GrTexture*,
+ SkIRect,
+ GrColorType textureColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer>,
+ size_t offset,
+ size_t rowBytes) override;
+
+ bool onTransferPixelsFrom(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer>,
+ size_t offset) override;
bool onRegenerateMipMapLevels(GrTexture*) override;
@@ -225,13 +239,22 @@
void checkForFinishedCommandBuffers();
// Function that uploads data onto textures with private storage mode (GPU access only).
- bool uploadToTexture(GrMtlTexture* tex, int left, int top, int width, int height,
- GrColorType dataColorType, const GrMipLevel texels[], int mipLevels);
+ bool uploadToTexture(GrMtlTexture* tex,
+ SkIRect rect,
+ GrColorType dataColorType,
+ const GrMipLevel texels[],
+ int mipLevels);
+
// Function that fills texture levels with transparent black based on levelMask.
bool clearTexture(GrMtlTexture*, size_t bbp, uint32_t levelMask);
- bool readOrTransferPixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType dstColorType, id<MTLBuffer> transferBuffer, size_t offset,
- size_t imageBytes, size_t rowBytes);
+
+ bool readOrTransferPixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType dstColorType,
+ id<MTLBuffer> transferBuffer,
+ size_t offset,
+ size_t imageBytes,
+ size_t rowBytes);
sk_sp<GrAttachment> makeStencilAttachment(const GrBackendFormat& /*colorFormat*/,
SkISize dimensions, int numStencilSamples) override;
diff --git a/src/gpu/mtl/GrMtlGpu.mm b/src/gpu/mtl/GrMtlGpu.mm
index c44cdf9..7a5b762 100644
--- a/src/gpu/mtl/GrMtlGpu.mm
+++ b/src/gpu/mtl/GrMtlGpu.mm
@@ -340,22 +340,23 @@
return true;
}
-bool GrMtlGpu::uploadToTexture(GrMtlTexture* tex, int left, int top, int width, int height,
- GrColorType dataColorType, const GrMipLevel texels[],
+bool GrMtlGpu::uploadToTexture(GrMtlTexture* tex,
+ SkIRect rect,
+ GrColorType dataColorType,
+ const GrMipLevel texels[],
int mipLevelCount) {
SkASSERT(this->caps()->isFormatTexturable(tex->backendFormat()));
// The assumption is either that we have no mipmaps, or that our rect is the entire texture
- SkASSERT(1 == mipLevelCount ||
- (0 == left && 0 == top && width == tex->width() && height == tex->height()));
+ SkASSERT(mipLevelCount == 1 || rect == SkIRect::MakeSize(tex->dimensions()));
// We assume that if the texture has mip levels, we either upload to all the levels or just the
// first.
- SkASSERT(1 == mipLevelCount || mipLevelCount == (tex->maxMipmapLevel() + 1));
+ SkASSERT(mipLevelCount == 1 || mipLevelCount == (tex->maxMipmapLevel() + 1));
- if (!check_max_blit_width(width)) {
+ if (!check_max_blit_width(rect.width())) {
return false;
}
- if (width == 0 || height == 0) {
+ if (rect.isEmpty()) {
return false;
}
@@ -367,7 +368,7 @@
// Either upload only the first miplevel or all miplevels
SkASSERT(1 == mipLevelCount || mipLevelCount == (int)mtlTexture.mipmapLevelCount);
- if (1 == mipLevelCount && !texels[0].fPixels) {
+ if (mipLevelCount == 1 && !texels[0].fPixels) {
return true; // no data to upload
}
@@ -381,8 +382,10 @@
size_t bpp = GrColorTypeBytesPerPixel(dataColorType);
SkTArray<size_t> individualMipOffsets(mipLevelCount);
- size_t combinedBufferSize = GrComputeTightCombinedBufferSize(
- bpp, {width, height}, &individualMipOffsets, mipLevelCount);
+ size_t combinedBufferSize = GrComputeTightCombinedBufferSize(bpp,
+ rect.size(),
+ &individualMipOffsets,
+ mipLevelCount);
SkASSERT(combinedBufferSize);
@@ -401,10 +404,10 @@
char* bufferData = (char*)slice.fOffsetMapPtr;
GrMtlBuffer* mtlBuffer = static_cast<GrMtlBuffer*>(slice.fBuffer);
- int currentWidth = width;
- int currentHeight = height;
+ int currentWidth = rect.width();
+ int currentHeight = rect.height();
int layerHeight = tex->height();
- MTLOrigin origin = MTLOriginMake(left, top, 0);
+ MTLOrigin origin = MTLOriginMake(rect.left(), rect.top(), 0);
auto cmdBuffer = this->commandBuffer();
id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
@@ -1258,9 +1261,12 @@
return success;
}
-bool GrMtlGpu::onWritePixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType srcColorType,
- const GrMipLevel texels[], int mipLevelCount,
+bool GrMtlGpu::onWritePixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType srcColorType,
+ const GrMipLevel texels[],
+ int mipLevelCount,
bool prepForTexSampling) {
GrMtlTexture* mtlTexture = static_cast<GrMtlTexture*>(surface->asTexture());
// TODO: In principle we should be able to support pure rendertargets as well, but
@@ -1276,12 +1282,14 @@
SkASSERT(texels[i].fPixels);
}
#endif
- return this->uploadToTexture(mtlTexture, left, top, width, height, srcColorType, texels,
- mipLevelCount);
+ return this->uploadToTexture(mtlTexture, rect, srcColorType, texels, mipLevelCount);
}
-bool GrMtlGpu::onReadPixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
+bool GrMtlGpu::onReadPixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType dstColorType,
+ void* buffer,
size_t rowBytes) {
SkASSERT(surface);
@@ -1290,8 +1298,8 @@
}
int bpp = GrColorTypeBytesPerPixel(dstColorType);
- size_t transBufferRowBytes = bpp * width;
- size_t transBufferImageBytes = transBufferRowBytes * height;
+ size_t transBufferRowBytes = bpp*rect.width();
+ size_t transBufferImageBytes = transBufferRowBytes*rect.height();
// TODO: implement some way of reusing buffers instead of making a new one every time.
NSUInteger options = 0;
@@ -1313,23 +1321,35 @@
}
GrMtlBuffer* grMtlBuffer = static_cast<GrMtlBuffer*>(transferBuffer.get());
- if (!this->readOrTransferPixels(surface, left, top, width, height, dstColorType,
+ if (!this->readOrTransferPixels(surface,
+ rect,
+ dstColorType,
grMtlBuffer->mtlBuffer(),
- 0, transBufferImageBytes, transBufferRowBytes)) {
+ 0,
+ transBufferImageBytes,
+ transBufferRowBytes)) {
return false;
}
this->submitCommandBuffer(kForce_SyncQueue);
const void* mappedMemory = grMtlBuffer->mtlBuffer().contents;
- SkRectMemcpy(buffer, rowBytes, mappedMemory, transBufferRowBytes, transBufferRowBytes, height);
+ SkRectMemcpy(buffer,
+ rowBytes,
+ mappedMemory,
+ transBufferRowBytes,
+ transBufferRowBytes,
+ rect.height());
return true;
}
-bool GrMtlGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int width, int height,
- GrColorType textureColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset,
+bool GrMtlGpu::onTransferPixelsTo(GrTexture* texture,
+ SkIRect rect,
+ GrColorType textureColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer> transferBuffer,
+ size_t offset,
size_t rowBytes) {
SkASSERT(texture);
SkASSERT(transferBuffer);
@@ -1353,15 +1373,15 @@
return false;
}
- MTLOrigin origin = MTLOriginMake(left, top, 0);
+ MTLOrigin origin = MTLOriginMake(rect.left(), rect.top(), 0);
auto cmdBuffer = this->commandBuffer();
id<MTLBlitCommandEncoder> GR_NORETAIN blitCmdEncoder = cmdBuffer->getBlitCommandEncoder();
[blitCmdEncoder copyFromBuffer: mtlBuffer
sourceOffset: offset + grMtlBuffer->offset()
sourceBytesPerRow: rowBytes
- sourceBytesPerImage: rowBytes*height
- sourceSize: MTLSizeMake(width, height, 1)
+ sourceBytesPerImage: rowBytes*rect.height()
+ sourceSize: MTLSizeMake(rect.width(), rect.height(), 1)
toTexture: mtlTexture
destinationSlice: 0
destinationLevel: 0
@@ -1370,9 +1390,12 @@
return true;
}
-bool GrMtlGpu::onTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset) {
+bool GrMtlGpu::onTransferPixelsFrom(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer> transferBuffer,
+ size_t offset) {
SkASSERT(surface);
SkASSERT(transferBuffer);
@@ -1391,18 +1414,26 @@
GrMtlBuffer* grMtlBuffer = static_cast<GrMtlBuffer*>(transferBuffer.get());
- size_t transBufferRowBytes = bpp * width;
- size_t transBufferImageBytes = transBufferRowBytes * height;
+ size_t transBufferRowBytes = bpp*rect.width();
+ size_t transBufferImageBytes = transBufferRowBytes*rect.height();
- return this->readOrTransferPixels(surface, left, top, width, height, bufferColorType,
- grMtlBuffer->mtlBuffer(), offset + grMtlBuffer->offset(),
- transBufferImageBytes, transBufferRowBytes);
+ return this->readOrTransferPixels(surface,
+ rect,
+ bufferColorType,
+ grMtlBuffer->mtlBuffer(),
+ offset + grMtlBuffer->offset(),
+ transBufferImageBytes,
+ transBufferRowBytes);
}
-bool GrMtlGpu::readOrTransferPixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType dstColorType, id<MTLBuffer> transferBuffer,
- size_t offset, size_t imageBytes, size_t rowBytes) {
- if (!check_max_blit_width(width)) {
+bool GrMtlGpu::readOrTransferPixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType dstColorType,
+ id<MTLBuffer> transferBuffer,
+ size_t offset,
+ size_t imageBytes,
+ size_t rowBytes) {
+ if (!check_max_blit_width(rect.width())) {
return false;
}
@@ -1427,8 +1458,8 @@
[blitCmdEncoder copyFromTexture: mtlTexture
sourceSlice: 0
sourceLevel: 0
- sourceOrigin: MTLOriginMake(left, top, 0)
- sourceSize: MTLSizeMake(width, height, 1)
+ sourceOrigin: MTLOriginMake(rect.left(), rect.top(), 0)
+ sourceSize: MTLSizeMake(rect.width(), rect.height(), 1)
toBuffer: transferBuffer
destinationOffset: offset
destinationBytesPerRow: rowBytes
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index cea30b0..b0f1b90 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -475,9 +475,12 @@
return buff;
}
-bool GrVkGpu::onWritePixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType srcColorType,
- const GrMipLevel texels[], int mipLevelCount,
+bool GrVkGpu::onWritePixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType srcColorType,
+ const GrMipLevel texels[],
+ int mipLevelCount,
bool prepForTexSampling) {
GrVkTexture* texture = static_cast<GrVkTexture*>(surface->asTexture());
if (!texture) {
@@ -509,12 +512,18 @@
return false;
}
}
- success = this->uploadTexDataLinear(texAttachment, left, top, width, height, srcColorType,
- texels[0].fPixels, texels[0].fRowBytes);
+ success = this->uploadTexDataLinear(texAttachment,
+ rect,
+ srcColorType,
+ texels[0].fPixels,
+ texels[0].fRowBytes);
} else {
SkASSERT(mipLevelCount <= (int)texAttachment->mipLevels());
- success = this->uploadTexDataOptimal(texAttachment, left, top, width, height, srcColorType,
- texels, mipLevelCount);
+ success = this->uploadTexDataOptimal(texAttachment,
+ rect,
+ srcColorType,
+ texels,
+ mipLevelCount);
if (1 == mipLevelCount) {
texture->markMipmapsDirty();
}
@@ -531,9 +540,12 @@
return success;
}
-bool GrVkGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t bufferOffset,
+bool GrVkGpu::onTransferPixelsTo(GrTexture* texture,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer> transferBuffer,
+ size_t bufferOffset,
size_t rowBytes) {
if (!this->currentCommandBuffer()) {
return false;
@@ -567,11 +579,7 @@
}
SkASSERT(GrVkFormatBytesPerBlock(format) == GrColorTypeBytesPerPixel(bufferColorType));
- SkDEBUGCODE(
- SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
- SkIRect bounds = SkIRect::MakeWH(texture->width(), texture->height());
- SkASSERT(bounds.contains(subRect));
- )
+ SkASSERT(SkIRect::MakeSize(texture->dimensions()).contains(rect));
// Set up copy region
VkBufferImageCopy region;
@@ -580,8 +588,8 @@
region.bufferRowLength = (uint32_t)(rowBytes/bpp);
region.bufferImageHeight = 0;
region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
- region.imageOffset = { left, top, 0 };
- region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 };
+ region.imageOffset = { rect.left(), rect.top(), 0 };
+ region.imageExtent = { (uint32_t)rect.width(), (uint32_t)rect.height(), 1 };
// Change layout of our target so it can be copied to
vkTex->setImageLayout(this,
@@ -605,9 +613,12 @@
return true;
}
-bool GrVkGpu::onTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset) {
+bool GrVkGpu::onTransferPixelsFrom(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer> transferBuffer,
+ size_t offset) {
if (!this->currentCommandBuffer()) {
return false;
}
@@ -644,11 +655,11 @@
VkBufferImageCopy region;
memset(®ion, 0, sizeof(VkBufferImageCopy));
region.bufferOffset = offset;
- region.bufferRowLength = width;
+ region.bufferRowLength = rect.width();
region.bufferImageHeight = 0;
region.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
- region.imageOffset = { left, top, 0 };
- region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 };
+ region.imageOffset = {rect.left(), rect.top(), 0};
+ region.imageExtent = {(uint32_t)rect.width(), (uint32_t)rect.height(), 1};
srcImage->setImageLayout(this,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
@@ -729,19 +740,18 @@
SkIPoint::Make(resolveRect.x(), resolveRect.y()));
}
-bool GrVkGpu::uploadTexDataLinear(GrVkAttachment* texAttachment, int left, int top, int width,
- int height, GrColorType dataColorType, const void* data,
+bool GrVkGpu::uploadTexDataLinear(GrVkAttachment* texAttachment,
+ SkIRect rect,
+ GrColorType dataColorType,
+ const void* data,
size_t rowBytes) {
SkASSERT(data);
SkASSERT(texAttachment->isLinearTiled());
- SkDEBUGCODE(
- SkIRect subRect = SkIRect::MakeXYWH(left, top, width, height);
- SkIRect bounds = SkIRect::MakeWH(texAttachment->width(), texAttachment->height());
- SkASSERT(bounds.contains(subRect));
- )
+ SkASSERT(SkIRect::MakeSize(texAttachment->dimensions()).contains(rect));
+
size_t bpp = GrColorTypeBytesPerPixel(dataColorType);
- size_t trimRowBytes = width * bpp;
+ size_t trimRowBytes = rect.width() * bpp;
SkASSERT(VK_IMAGE_LAYOUT_PREINITIALIZED == texAttachment->currentLayout() ||
VK_IMAGE_LAYOUT_GENERAL == texAttachment->currentLayout());
@@ -763,8 +773,8 @@
if (VK_NULL_HANDLE == alloc.fMemory) {
return false;
}
- VkDeviceSize offset = top * layout.rowPitch + left * bpp;
- VkDeviceSize size = height*layout.rowPitch;
+ VkDeviceSize offset = rect.top()*layout.rowPitch + rect.left()*bpp;
+ VkDeviceSize size = rect.height()*layout.rowPitch;
SkASSERT(size + offset <= alloc.fSize);
void* mapPtr = GrVkMemory::MapAlloc(this, alloc);
if (!mapPtr) {
@@ -772,8 +782,12 @@
}
mapPtr = reinterpret_cast<char*>(mapPtr) + offset;
- SkRectMemcpy(mapPtr, static_cast<size_t>(layout.rowPitch), data, rowBytes, trimRowBytes,
- height);
+ SkRectMemcpy(mapPtr,
+ static_cast<size_t>(layout.rowPitch),
+ data,
+ rowBytes,
+ trimRowBytes,
+ rect.height());
GrVkMemory::FlushMappedAlloc(this, alloc, offset, size);
GrVkMemory::UnmapAlloc(this, alloc);
@@ -840,8 +854,10 @@
return bufferSize;
}
-bool GrVkGpu::uploadTexDataOptimal(GrVkAttachment* texAttachment, int left, int top, int width,
- int height, GrColorType dataColorType, const GrMipLevel texels[],
+bool GrVkGpu::uploadTexDataOptimal(GrVkAttachment* texAttachment,
+ SkIRect rect,
+ GrColorType dataColorType,
+ const GrMipLevel texels[],
int mipLevelCount) {
if (!this->currentCommandBuffer()) {
return false;
@@ -849,17 +865,13 @@
SkASSERT(!texAttachment->isLinearTiled());
// The assumption is either that we have no mipmaps, or that our rect is the entire texture
- SkASSERT(1 == mipLevelCount ||
- (0 == left && 0 == top && width == texAttachment->width() &&
- height == texAttachment->height()));
+ SkASSERT(mipLevelCount == 1 || rect == SkIRect::MakeSize(texAttachment->dimensions()));
// We assume that if the texture has mip levels, we either upload to all the levels or just the
// first.
- SkASSERT(1 == mipLevelCount || mipLevelCount == (int)texAttachment->mipLevels());
+ SkASSERT(mipLevelCount == 1 || mipLevelCount == (int)texAttachment->mipLevels());
- if (width == 0 || height == 0) {
- return false;
- }
+ SkASSERT(!rect.isEmpty());
SkASSERT(this->vkCaps().surfaceSupportsWritePixels(texAttachment));
@@ -876,12 +888,12 @@
size_t combinedBufferSize;
if (mipLevelCount > 1) {
combinedBufferSize = GrComputeTightCombinedBufferSize(bpp,
- {width, height},
+ rect.size(),
&individualMipOffsets,
mipLevelCount);
} else {
SkASSERT(texelsShallowCopy[0].fPixels && texelsShallowCopy[0].fRowBytes);
- combinedBufferSize = width*height*bpp;
+ combinedBufferSize = rect.width()*rect.height()*bpp;
individualMipOffsets.push_back(0);
}
SkASSERT(combinedBufferSize);
@@ -900,14 +912,14 @@
return false;
}
- int uploadLeft = left;
- int uploadTop = top;
+ int uploadLeft = rect.left();
+ int uploadTop = rect.top();
char* buffer = (char*) slice.fOffsetMapPtr;
SkTArray<VkBufferImageCopy> regions(mipLevelCount);
- int currentWidth = width;
- int currentHeight = height;
+ int currentWidth = rect.width();
+ int currentHeight = rect.height();
int layerHeight = texAttachment->height();
for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; currentMipLevel++) {
if (texelsShallowCopy[currentMipLevel].fPixels) {
@@ -2330,8 +2342,11 @@
return false;
}
-bool GrVkGpu::onReadPixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
+bool GrVkGpu::onReadPixels(GrSurface* surface,
+ SkIRect rect,
+ GrColorType surfaceColorType,
+ GrColorType dstColorType,
+ void* buffer,
size_t rowBytes) {
if (surface->isProtected()) {
return false;
@@ -2375,13 +2390,13 @@
if (GrVkFormatBytesPerBlock(image->imageFormat()) != bpp) {
return false;
}
- size_t tightRowBytes = bpp * width;
+ size_t tightRowBytes = bpp*rect.width();
VkBufferImageCopy region;
memset(®ion, 0, sizeof(VkBufferImageCopy));
- VkOffset3D offset = { left, top, 0 };
+ VkOffset3D offset = { rect.left(), rect.top(), 0 };
region.imageOffset = offset;
- region.imageExtent = { (uint32_t)width, (uint32_t)height, 1 };
+ region.imageExtent = { (uint32_t)rect.width(), (uint32_t)rect.height(), 1 };
size_t transBufferRowBytes = bpp * region.imageExtent.width;
size_t imageRows = region.imageExtent.height;
@@ -2423,7 +2438,7 @@
}
void* mappedMemory = transferBuffer->map();
- SkRectMemcpy(buffer, rowBytes, mappedMemory, transBufferRowBytes, tightRowBytes, height);
+ SkRectMemcpy(buffer, rowBytes, mappedMemory, transBufferRowBytes, tightRowBytes, rect.height());
transferBuffer->unmap();
return true;
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 30a5edc..7ac6e39 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -268,22 +268,35 @@
sk_sp<GrGpuBuffer> onCreateBuffer(size_t size, GrGpuBufferType type, GrAccessPattern,
const void* data) override;
- bool onReadPixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType dstColorType, void* buffer,
+ bool onReadPixels(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType dstColorType,
+ void* buffer,
size_t rowBytes) override;
- bool onWritePixels(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType srcColorType,
- const GrMipLevel texels[], int mipLevelCount,
+ bool onWritePixels(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType srcColorType,
+ const GrMipLevel[],
+ int mipLevelCount,
bool prepForTexSampling) override;
- bool onTransferPixelsTo(GrTexture*, int left, int top, int width, int height,
- GrColorType textureColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset,
+ bool onTransferPixelsTo(GrTexture*,
+ SkIRect,
+ GrColorType textureColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer>,
+ size_t offset,
size_t rowBytes) override;
- bool onTransferPixelsFrom(GrSurface* surface, int left, int top, int width, int height,
- GrColorType surfaceColorType, GrColorType bufferColorType,
- sk_sp<GrGpuBuffer> transferBuffer, size_t offset) override;
+
+ bool onTransferPixelsFrom(GrSurface*,
+ SkIRect,
+ GrColorType surfaceColorType,
+ GrColorType bufferColorType,
+ sk_sp<GrGpuBuffer>,
+ size_t offset) override;
bool onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
const SkIPoint& dstPoint) override;
@@ -331,10 +344,16 @@
const SkIPoint& dstPoint);
// helpers for onCreateTexture and writeTexturePixels
- bool uploadTexDataLinear(GrVkAttachment* tex, int left, int top, int width, int height,
- GrColorType colorType, const void* data, size_t rowBytes);
- bool uploadTexDataOptimal(GrVkAttachment* tex, int left, int top, int width, int height,
- GrColorType colorType, const GrMipLevel texels[], int mipLevelCount);
+ bool uploadTexDataLinear(GrVkAttachment* tex,
+ SkIRect rect,
+ GrColorType colorType,
+ const void* data,
+ size_t rowBytes);
+ bool uploadTexDataOptimal(GrVkAttachment* tex,
+ SkIRect rect,
+ GrColorType colorType,
+ const GrMipLevel texels[],
+ int mipLevelCount);
bool uploadTexDataCompressed(GrVkAttachment* tex, SkImage::CompressionType compression,
VkFormat vkFormat, SkISize dimensions, GrMipmapped mipMapped,
const void* data, size_t dataSize);
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index 79aae77..0f94d5e 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -389,9 +389,12 @@
// Try the low level write.
dContext->flushAndSubmit();
auto gpuWriteResult = dContext->priv().getGpu()->writePixels(
- proxy->peekTexture(), 0, 0, kSize, kSize, GrColorType::kRGBA_8888,
- GrColorType::kRGBA_8888, write.addr32(),
- kSize * GrColorTypeBytesPerPixel(GrColorType::kRGBA_8888));
+ proxy->peekTexture(),
+ SkIRect::MakeWH(kSize, kSize),
+ GrColorType::kRGBA_8888,
+ GrColorType::kRGBA_8888,
+ write.addr32(),
+ kSize*GrColorTypeBytesPerPixel(GrColorType::kRGBA_8888));
REPORTER_ASSERT(reporter, gpuWriteResult == (ioType == kRW_GrIOType));
SkBitmap copySrcBitmap;
diff --git a/tests/TransferPixelsTest.cpp b/tests/TransferPixelsTest.cpp
index b832978..6b403ec 100644
--- a/tests/TransferPixelsTest.cpp
+++ b/tests/TransferPixelsTest.cpp
@@ -82,8 +82,12 @@
if (supportedRead.fColorType != colorType) {
size_t tmpRowBytes = GrColorTypeBytesPerPixel(supportedRead.fColorType) * w;
std::unique_ptr<char[]> tmpPixels(new char[tmpRowBytes * h]);
- if (!gpu->readPixels(texture, 0, 0, w, h, colorType, supportedRead.fColorType,
- tmpPixels.get(), tmpRowBytes)) {
+ if (!gpu->readPixels(texture,
+ SkIRect::MakeWH(w, h),
+ colorType,
+ supportedRead.fColorType,
+ tmpPixels.get(),
+ tmpRowBytes)) {
return false;
}
GrImageInfo tmpInfo(supportedRead.fColorType, kUnpremul_SkAlphaType, nullptr, w, h);
@@ -92,7 +96,12 @@
return GrConvertPixels(GrPixmap(dstInfo, dst, rowBytes),
GrPixmap(tmpInfo, tmpPixels.get(), tmpRowBytes));
}
- return gpu->readPixels(texture, 0, 0, w, h, colorType, supportedRead.fColorType, dst, rowBytes);
+ return gpu->readPixels(texture,
+ SkIRect::MakeWH(w, h),
+ colorType,
+ supportedRead.fColorType,
+ dst,
+ rowBytes);
}
void basic_transfer_to_test(skiatest::Reporter* reporter,
@@ -170,8 +179,13 @@
// transfer full data
bool result;
- result = gpu->transferPixelsTo(tex.get(), 0, 0, kTexDims.fWidth, kTexDims.fHeight, colorType,
- allowedSrc.fColorType, buffer, 0, srcRowBytes);
+ result = gpu->transferPixelsTo(tex.get(),
+ SkIRect::MakeSize(kTexDims),
+ colorType,
+ allowedSrc.fColorType,
+ buffer,
+ 0,
+ srcRowBytes);
REPORTER_ASSERT(reporter, result);
size_t dstRowBytes = GrColorTypeBytesPerPixel(colorType) * kTexDims.fWidth;
@@ -237,8 +251,13 @@
memcpy(data, srcData.get(), size);
buffer->unmap();
- result = gpu->transferPixelsTo(tex.get(), left, top, width, height, colorType,
- allowedSrc.fColorType, buffer, offset, srcRowBytes);
+ result = gpu->transferPixelsTo(tex.get(),
+ SkIRect::MakeXYWH(left, top, width, height),
+ colorType,
+ allowedSrc.fColorType,
+ buffer,
+ offset,
+ srcRowBytes);
if (!result) {
ERRORF(reporter, "Could not transfer pixels to texture, color type: %d",
static_cast<int>(colorType));
@@ -340,8 +359,12 @@
//////////////////////////
// transfer full data
- bool result = gpu->transferPixelsFrom(tex.get(), 0, 0, kTexDims.fWidth, kTexDims.fHeight,
- colorType, allowedRead.fColorType, buffer, 0);
+ bool result = gpu->transferPixelsFrom(tex.get(),
+ SkIRect::MakeSize(kTexDims),
+ colorType,
+ allowedRead.fColorType,
+ buffer,
+ 0);
if (!result) {
ERRORF(reporter, "transferPixelsFrom failed.");
return;
@@ -382,9 +405,13 @@
///////////////////////
// Now test a partial read at an offset into the buffer.
- result = gpu->transferPixelsFrom(tex.get(), kPartialLeft, kPartialTop, kPartialWidth,
- kPartialHeight, colorType, allowedRead.fColorType,
- buffer, partialReadOffset);
+ result = gpu->transferPixelsFrom(
+ tex.get(),
+ SkIRect::MakeXYWH(kPartialLeft, kPartialTop, kPartialWidth, kPartialHeight),
+ colorType,
+ allowedRead.fColorType,
+ buffer,
+ partialReadOffset);
if (!result) {
ERRORF(reporter, "transferPixelsFrom failed.");
return;