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>
This commit is contained in:
parent
f76602e3bf
commit
e2078f1106
@ -58,8 +58,11 @@ public:
|
||||
// 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();
|
||||
|
@ -115,9 +115,11 @@ private:
|
||||
* 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
|
||||
|
@ -176,8 +176,11 @@ void GrDrawOpAtlas::Plot::uploadToTexture(GrDeferredTextureUploadWritePixelsFn&
|
||||
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;)
|
||||
}
|
||||
|
@ -207,8 +207,12 @@ sk_sp<GrTexture> GrGpu::createTexture(SkISize dimensions,
|
||||
// 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 @@ bool GrGpu::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
|
||||
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 @@ bool GrGpu::readPixels(GrSurface* surface, int left, int top, int width, int hei
|
||||
|
||||
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 @@ bool GrGpu::writePixels(GrSurface* surface, int left, int top, int width, int he
|
||||
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 @@ bool GrGpu::writePixels(GrSurface* surface, int left, int top, int width, int he
|
||||
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 @@ bool GrGpu::transferPixelsTo(GrTexture* texture, int left, int top, int width, i
|
||||
}
|
||||
|
||||
// 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 @@ bool GrGpu::transferPixelsTo(GrTexture* texture, int left, int top, int width, i
|
||||
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 @@ bool GrGpu::transferPixelsFrom(GrSurface* surface, int left, int top, int width,
|
||||
#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;
|
||||
}
|
||||
|
121
src/gpu/GrGpu.h
121
src/gpu/GrGpu.h
@ -219,11 +219,8 @@ public:
|
||||
/**
|
||||
* 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 @@ public:
|
||||
* 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 @@ public:
|
||||
* 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 @@ public:
|
||||
* 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 @@ private:
|
||||
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;
|
||||
|
||||
|
@ -100,24 +100,27 @@ void GrOpFlushState::reset() {
|
||||
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 @@ void GrOpFlushState::doUpload(GrDeferredTextureUploadFn& upload,
|
||||
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);
|
||||
|
@ -728,7 +728,11 @@ sk_sp<GrTexture> GrResourceProvider::writePixels(sk_sp<GrTexture> texture,
|
||||
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;
|
||||
}
|
||||
|
@ -343,9 +343,12 @@ bool GrSurfaceContext::readPixels(GrDirectContext* dContext, GrPixmap dst, SkIPo
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,10 @@ bool GrTransferFromRenderTask::onExecute(GrOpFlushState* flushState) {
|
||||
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);
|
||||
}
|
||||
|
@ -61,10 +61,7 @@ bool GrWritePixelsTask::onExecute(GrOpFlushState* flushState) {
|
||||
}
|
||||
GrSurface* dstSurface = dstProxy->peekSurface();
|
||||
return flushState->gpu()->writePixels(dstSurface,
|
||||
fRect.fLeft,
|
||||
fRect.fTop,
|
||||
fRect.width(),
|
||||
fRect.height(),
|
||||
fRect,
|
||||
fDstColorType,
|
||||
fSrcColorType,
|
||||
fLevels.get(),
|
||||
|
@ -556,8 +556,11 @@ void GrD3DGpu::onResolveRenderTarget(GrRenderTarget* target, const SkIRect& reso
|
||||
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 @@ bool GrD3DGpu::onReadPixels(GrSurface* surface, int left, int top, int width, in
|
||||
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 @@ bool GrD3DGpu::onReadPixels(GrSurface* surface, int left, int top, int width, in
|
||||
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 @@ bool GrD3DGpu::onReadPixels(GrSurface* surface, int left, int top, int width, in
|
||||
}
|
||||
|
||||
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 @@ void GrD3DGpu::readOrTransferPixels(GrD3DTextureResource* texResource,
|
||||
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 @@ void GrD3DGpu::readOrTransferPixels(GrD3DTextureResource* texResource,
|
||||
&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 @@ bool GrD3DGpu::onWritePixels(GrSurface* surface, int left, int top, int width, i
|
||||
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 @@ bool GrD3DGpu::onWritePixels(GrSurface* surface, int left, int top, int width, i
|
||||
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 @@ bool GrD3DGpu::uploadToTexture(GrD3DTexture* tex, int left, int top, int width,
|
||||
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 @@ bool GrD3DGpu::uploadToTexture(GrD3DTexture* tex, int left, int top, int width,
|
||||
|
||||
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 @@ bool GrD3DGpu::uploadToTexture(GrD3DTexture* tex, int left, int top, int width,
|
||||
}
|
||||
|
||||
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 @@ bool GrD3DGpu::uploadToTexture(GrD3DTexture* tex, int left, int top, int width,
|
||||
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 @@ bool GrD3DGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int wid
|
||||
|
||||
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 @@ bool GrD3DGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int wid
|
||||
|
||||
// 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 @@ bool GrD3DGpu::onTransferPixelsFrom(GrSurface* surface, int left, int top, int w
|
||||
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.
|
||||
|
@ -165,22 +165,35 @@ private:
|
||||
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 @@ private:
|
||||
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);
|
||||
|
||||
|
@ -178,33 +178,41 @@ sk_sp<GrGpuBuffer> GrDawnGpu::onCreateBuffer(size_t size, GrGpuBufferType type,
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
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 void callback(WGPUBufferMapAsyncStatus status, void* userdata) {
|
||||
*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 @@ bool GrDawnGpu::onReadPixels(GrSurface* surface, int left, int top, int width, i
|
||||
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 @@ bool GrDawnGpu::onReadPixels(GrSurface* surface, int left, int top, int width, i
|
||||
|
||||
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 @@ bool GrDawnGpu::onReadPixels(GrSurface* surface, int left, int top, int width, i
|
||||
} 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;
|
||||
|
@ -160,23 +160,35 @@ private:
|
||||
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 {}
|
||||
|
||||
|
@ -815,9 +815,12 @@ static bool check_write_and_transfer_input(GrGLTexture* glTex) {
|
||||
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 @@ bool GrGLGpu::onWritePixels(GrSurface* surface, int left, int top, int width, in
|
||||
}
|
||||
|
||||
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 @@ bool GrGLGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int widt
|
||||
}
|
||||
|
||||
static_assert(sizeof(int) == sizeof(int32_t), "");
|
||||
if (width <= 0 || height <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this->bindTextureToScratchUnit(glTex->target(), glTex->textureID());
|
||||
|
||||
@ -876,18 +883,11 @@ bool GrGLGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int widt
|
||||
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 @@ bool GrGLGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int widt
|
||||
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 @@ bool GrGLGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int widt
|
||||
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 @@ void GrGLGpu::clearStencilClip(const GrScissorState& scissor, bool insideStencil
|
||||
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 @@ bool GrGLGpu::readOrTransferPixelsFrom(GrSurface* surface, int left, int top, in
|
||||
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 @@ bool GrGLGpu::readOrTransferPixelsFrom(GrSurface* surface, int left, int top, in
|
||||
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 @@ bool GrGLGpu::onReadPixels(GrSurface* surface, int left, int top, int width, int
|
||||
// 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(
|
||||
|
@ -295,25 +295,42 @@ private:
|
||||
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
|
||||
|
@ -90,30 +90,44 @@ private:
|
||||
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;
|
||||
|
@ -179,21 +179,35 @@ private:
|
||||
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 @@ private:
|
||||
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;
|
||||
|
@ -340,22 +340,23 @@ static bool check_max_blit_width(int widthInPixels) {
|
||||
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 @@ bool GrMtlGpu::uploadToTexture(GrMtlTexture* tex, int left, int top, int width,
|
||||
// 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 @@ bool GrMtlGpu::uploadToTexture(GrMtlTexture* tex, int left, int top, int width,
|
||||
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 @@ bool GrMtlGpu::uploadToTexture(GrMtlTexture* tex, int left, int top, int width,
|
||||
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 @@ bool GrMtlGpu::onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcR
|
||||
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 @@ bool GrMtlGpu::onWritePixels(GrSurface* surface, int left, int top, int width, i
|
||||
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 @@ bool GrMtlGpu::onReadPixels(GrSurface* surface, int left, int top, int width, in
|
||||
}
|
||||
|
||||
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 @@ bool GrMtlGpu::onReadPixels(GrSurface* surface, int left, int top, int width, in
|
||||
}
|
||||
|
||||
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 @@ bool GrMtlGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int wid
|
||||
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 @@ bool GrMtlGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int wid
|
||||
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 @@ bool GrMtlGpu::onTransferPixelsFrom(GrSurface* surface, int left, int top, int w
|
||||
|
||||
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 @@ bool GrMtlGpu::readOrTransferPixels(GrSurface* surface, int left, int top, int w
|
||||
[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
|
||||
|
@ -475,9 +475,12 @@ sk_sp<GrGpuBuffer> GrVkGpu::onCreateBuffer(size_t size, GrGpuBufferType type,
|
||||
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 @@ bool GrVkGpu::onWritePixels(GrSurface* surface, int left, int top, int width, in
|
||||
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 @@ bool GrVkGpu::onWritePixels(GrSurface* surface, int left, int top, int width, in
|
||||
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 @@ bool GrVkGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int widt
|
||||
}
|
||||
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 @@ bool GrVkGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int widt
|
||||
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 @@ bool GrVkGpu::onTransferPixelsTo(GrTexture* texture, int left, int top, int widt
|
||||
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 @@ bool GrVkGpu::onTransferPixelsFrom(GrSurface* surface, int left, int top, int wi
|
||||
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 @@ void GrVkGpu::onResolveRenderTarget(GrRenderTarget* target, const SkIRect& resol
|
||||
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 @@ bool GrVkGpu::uploadTexDataLinear(GrVkAttachment* texAttachment, int left, int t
|
||||
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 @@ bool GrVkGpu::uploadTexDataLinear(GrVkAttachment* texAttachment, int left, int t
|
||||
}
|
||||
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 @@ static size_t fill_in_compressed_regions(GrStagingBufferManager* stagingBufferMa
|
||||
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 @@ bool GrVkGpu::uploadTexDataOptimal(GrVkAttachment* texAttachment, int left, int
|
||||
|
||||
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 @@ bool GrVkGpu::uploadTexDataOptimal(GrVkAttachment* texAttachment, int left, int
|
||||
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 @@ bool GrVkGpu::uploadTexDataOptimal(GrVkAttachment* texAttachment, int left, int
|
||||
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 @@ bool GrVkGpu::onCopySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRe
|
||||
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 @@ bool GrVkGpu::onReadPixels(GrSurface* surface, int left, int top, int width, int
|
||||
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 @@ bool GrVkGpu::onReadPixels(GrSurface* surface, int left, int top, int width, int
|
||||
}
|
||||
void* mappedMemory = transferBuffer->map();
|
||||
|
||||
SkRectMemcpy(buffer, rowBytes, mappedMemory, transBufferRowBytes, tightRowBytes, height);
|
||||
SkRectMemcpy(buffer, rowBytes, mappedMemory, transBufferRowBytes, tightRowBytes, rect.height());
|
||||
|
||||
transferBuffer->unmap();
|
||||
return true;
|
||||
|
@ -268,22 +268,35 @@ private:
|
||||
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 @@ private:
|
||||
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);
|
||||
|
@ -389,9 +389,12 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadOnlyTexture, reporter, context_info) {
|
||||
// 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;
|
||||
|
@ -82,8 +82,12 @@ bool read_pixels_from_texture(GrTexture* texture, GrColorType colorType, char* d
|
||||
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 @@ bool read_pixels_from_texture(GrTexture* texture, GrColorType colorType, char* d
|
||||
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 @@ void basic_transfer_to_test(skiatest::Reporter* reporter,
|
||||
// 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 @@ void basic_transfer_to_test(skiatest::Reporter* reporter,
|
||||
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 @@ void basic_transfer_from_test(skiatest::Reporter* reporter, const sk_gpu_test::C
|
||||
|
||||
//////////////////////////
|
||||
// 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 @@ void basic_transfer_from_test(skiatest::Reporter* reporter, const sk_gpu_test::C
|
||||
|
||||
///////////////////////
|
||||
// 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;
|
||||
|
Loading…
Reference in New Issue
Block a user