aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gn/tests.gni1
-rw-r--r--src/gpu/GrGpu.cpp16
-rw-r--r--src/gpu/GrGpu.h19
-rw-r--r--src/gpu/gl/GrGLBuffer.cpp6
-rw-r--r--src/gpu/gl/GrGLCaps.cpp10
-rw-r--r--src/gpu/gl/GrGLGpu.cpp151
-rw-r--r--src/gpu/gl/GrGLGpu.h7
-rw-r--r--src/gpu/vk/GrVkGpu.cpp62
-rw-r--r--src/gpu/vk/GrVkGpu.h4
-rwxr-xr-xtests/TransferPixelsTest.cpp173
-rw-r--r--tools/gpu/GrTest.cpp2
11 files changed, 84 insertions, 367 deletions
diff --git a/gn/tests.gni b/gn/tests.gni
index 6843a6f555..80af7146e7 100644
--- a/gn/tests.gni
+++ b/gn/tests.gni
@@ -252,7 +252,6 @@ tests_sources = [
"$_tests/TopoSortTest.cpp",
"$_tests/TraceMemoryDumpTest.cpp",
"$_tests/TracingTest.cpp",
- "$_tests/TransferPixelsTest.cpp",
"$_tests/TypefaceTest.cpp",
"$_tests/UnicodeTest.cpp",
"$_tests/UtilsTest.cpp",
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index e0766a730f..262f155c24 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -389,24 +389,30 @@ bool GrGpu::writePixels(GrSurface* surface,
return this->writePixels(surface, left, top, width, height, config, texels);
}
-bool GrGpu::transferPixels(GrTexture* texture,
+bool GrGpu::transferPixels(GrSurface* surface,
int left, int top, int width, int height,
GrPixelConfig config, GrBuffer* transferBuffer,
- size_t offset, size_t rowBytes) {
+ size_t offset, size_t rowBytes, GrFence* fence) {
SkASSERT(transferBuffer);
+ SkASSERT(fence);
// We don't allow conversion between integer configs and float/fixed configs.
- if (GrPixelConfigIsSint(texture->config()) != GrPixelConfigIsSint(config)) {
+ if (GrPixelConfigIsSint(surface->config()) != GrPixelConfigIsSint(config)) {
return false;
}
this->handleDirtyContext();
- if (this->onTransferPixels(texture, left, top, width, height, config,
+ if (this->onTransferPixels(surface, left, top, width, height, config,
transferBuffer, offset, rowBytes)) {
SkIRect rect = SkIRect::MakeXYWH(left, top, width, height);
- this->didWriteToSurface(texture, &rect);
+ this->didWriteToSurface(surface, &rect);
fStats.incTransfersToTexture();
+ if (*fence) {
+ this->deleteFence(*fence);
+ }
+ *fence = this->insertFence();
+
return true;
}
return false;
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index d413fd62bb..418b8b418d 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -291,26 +291,23 @@ public:
size_t rowBytes);
/**
- * Updates the pixels in a rectangle of a texture using a buffer
+ * Updates the pixels in a rectangle of a surface using a buffer
*
- * There are a couple of assumptions here. First, we only update the top miplevel.
- * And second, that any y flip needed has already been done in the buffer.
- *
- * @param texture The texture to write to.
+ * @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 config the pixel config of the source buffer
- * @param transferBuffer GrBuffer to read pixels from (type must be "kXferCpuToGpu")
+ * @param transferBuffer GrBuffer to read pixels from (type must be "kCpuToGpu")
* @param offset offset from the start of the buffer
- * @param rowBytes number of bytes between consecutive rows in the buffer. Zero
+ * @param rowBytes number of bytes between consecutive rows. Zero
* means rows are tightly packed.
*/
- bool transferPixels(GrTexture* texture,
+ bool transferPixels(GrSurface* surface,
int left, int top, int width, int height,
GrPixelConfig config, GrBuffer* transferBuffer,
- size_t offset, size_t rowBytes);
+ size_t offset, size_t rowBytes, GrFence* fence);
// After the client interacts directly with the 3D context state the GrGpu
// must resync its internal state and assumptions about 3D context state.
@@ -591,8 +588,8 @@ private:
GrPixelConfig config,
const SkTArray<GrMipLevel>& texels) = 0;
- // overridden by backend-specific derived class to perform the texture transfer
- virtual bool onTransferPixels(GrTexture*,
+ // overridden by backend-specific derived class to perform the surface write
+ virtual bool onTransferPixels(GrSurface*,
int left, int top, int width, int height,
GrPixelConfig config, GrBuffer* transferBuffer,
size_t offset, size_t rowBytes) = 0;
diff --git a/src/gpu/gl/GrGLBuffer.cpp b/src/gpu/gl/GrGLBuffer.cpp
index 180dc39958..7dfc6b81e7 100644
--- a/src/gpu/gl/GrGLBuffer.cpp
+++ b/src/gpu/gl/GrGLBuffer.cpp
@@ -31,12 +31,6 @@
GrGLBuffer* GrGLBuffer::Create(GrGLGpu* gpu, size_t size, GrBufferType intendedType,
GrAccessPattern accessPattern, const void* data) {
- if (gpu->glCaps().transferBufferType() == GrGLCaps::kNone_TransferBufferType &&
- (kXferCpuToGpu_GrBufferType == intendedType ||
- kXferGpuToCpu_GrBufferType == intendedType)) {
- return nullptr;
- }
-
sk_sp<GrGLBuffer> buffer(new GrGLBuffer(gpu, size, intendedType, accessPattern, data));
if (0 == buffer->bufferID()) {
return nullptr;
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index faea4e6395..95791f12bb 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -457,14 +457,10 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
fTransferBufferType = kPBO_TransferBufferType;
}
} else {
- if (version >= GR_GL_VER(3, 0) ||
- (ctxInfo.hasExtension("GL_NV_pixel_buffer_object") &&
- // GL_EXT_unpack_subimage needed to support subtexture rectangles
- ctxInfo.hasExtension("GL_EXT_unpack_subimage"))) {
+ if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_NV_pixel_buffer_object")) {
fTransferBufferType = kPBO_TransferBufferType;
-// TODO: get transfer buffers working in Chrome
-// } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
-// fTransferBufferType = kChromium_TransferBufferType;
+ } else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
+ fTransferBufferType = kChromium_TransferBufferType;
}
}
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index f63fc253a3..e5e8841c37 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -783,6 +783,36 @@ bool GrGLGpu::onWritePixels(GrSurface* surface,
left, top, width, height, config, texels);
}
+bool GrGLGpu::onTransferPixels(GrSurface* surface,
+ int left, int top, int width, int height,
+ GrPixelConfig config, GrBuffer* transferBuffer,
+ size_t offset, size_t rowBytes) {
+ GrGLTexture* glTex = static_cast<GrGLTexture*>(surface->asTexture());
+
+ if (!check_write_and_transfer_input(glTex, surface, config)) {
+ return false;
+ }
+
+ this->setScratchTextureUnit();
+ GL_CALL(BindTexture(glTex->target(), glTex->textureID()));
+
+ SkASSERT(!transferBuffer->isMapped());
+ SkASSERT(!transferBuffer->isCPUBacked());
+ const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(transferBuffer);
+ this->bindBuffer(kXferCpuToGpu_GrBufferType, glBuffer);
+
+ bool success = false;
+ GrMipLevel mipLevel;
+ mipLevel.fPixels = transferBuffer;
+ mipLevel.fRowBytes = rowBytes;
+ SkSTArray<1, GrMipLevel> texels;
+ texels.push_back(mipLevel);
+ success = this->uploadTexData(glTex->config(), glTex->width(), glTex->height(), glTex->origin(),
+ glTex->target(), kTransfer_UploadType, left, top, width, height,
+ config, texels);
+ return success;
+}
+
// For GL_[UN]PACK_ALIGNMENT.
static inline GrGLint config_alignment(GrPixelConfig config) {
switch (config) {
@@ -809,78 +839,6 @@ static inline GrGLint config_alignment(GrPixelConfig config) {
return 0;
}
-bool GrGLGpu::onTransferPixels(GrTexture* texture,
- int left, int top, int width, int height,
- GrPixelConfig config, GrBuffer* transferBuffer,
- size_t offset, size_t rowBytes) {
- GrGLTexture* glTex = static_cast<GrGLTexture*>(texture);
- GrPixelConfig texConfig = glTex->config();
- SkASSERT(this->caps()->isConfigTexturable(texConfig));
-
- if (!check_write_and_transfer_input(glTex, texture, config)) {
- return false;
- }
-
- if (width <= 0 || width > SK_MaxS32 || height <= 0 || height > SK_MaxS32) {
- return false;
- }
-
- this->setScratchTextureUnit();
- GL_CALL(BindTexture(glTex->target(), glTex->textureID()));
-
- SkASSERT(!transferBuffer->isMapped());
- SkASSERT(!transferBuffer->isCPUBacked());
- const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(transferBuffer);
- this->bindBuffer(kXferCpuToGpu_GrBufferType, glBuffer);
-
- size_t bpp = GrBytesPerPixel(config);
- const size_t trimRowBytes = width * bpp;
- const void* pixels = (void*)offset;
- if (!GrSurfacePriv::AdjustWritePixelParams(glTex->width(), glTex->height(), bpp,
- &left, &top,
- &width, &height,
- &pixels,
- &rowBytes)) {
- return false;
- }
- if (width < 0 || width < 0) {
- return false;
- }
-
- bool restoreGLRowLength = false;
- if (trimRowBytes != rowBytes) {
- // we should have checked for this support already
- SkASSERT(this->glCaps().unpackRowLengthSupport());
- GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowBytes / bpp));
- restoreGLRowLength = true;
- }
-
- // Internal format comes from the texture desc.
- GrGLenum internalFormat;
- // External format and type come from the upload data.
- GrGLenum externalFormat;
- GrGLenum externalType;
- if (!this->glCaps().getTexImageFormats(texConfig, config, &internalFormat,
- &externalFormat, &externalType)) {
- return false;
- }
-
- GL_CALL(PixelStorei(GR_GL_UNPACK_ALIGNMENT, config_alignment(texConfig)));
- GL_CALL(TexSubImage2D(glTex->target(),
- 0,
- left, top,
- width,
- height,
- externalFormat, externalType,
- pixels));
-
- if (restoreGLRowLength) {
- GL_CALL(PixelStorei(GR_GL_UNPACK_ROW_LENGTH, 0));
- }
-
- return true;
-}
-
/**
* Creates storage space for the texture and fills it with texels.
*
@@ -1013,13 +971,6 @@ bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight
const SkTArray<GrMipLevel>& texels) {
SkASSERT(this->caps()->isConfigTexturable(texConfig));
- // unbind any previous transfer buffer
- auto& xferBufferState = fHWBufferState[kXferCpuToGpu_GrBufferType];
- if (!xferBufferState.fBoundBufferUniqueID.isInvalid()) {
- GL_CALL(BindBuffer(xferBufferState.fGLTarget, 0));
- xferBufferState.invalidate();
- }
-
// texels is const.
// But we may need to flip the texture vertically to prepare it.
// Rather than flip in place and alter the incoming data,
@@ -1029,7 +980,7 @@ bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight
for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >= 0;
currentMipLevel--) {
- SkASSERT(texelsShallowCopy[currentMipLevel].fPixels);
+ SkASSERT(texelsShallowCopy[currentMipLevel].fPixels || kTransfer_UploadType == uploadType);
}
const GrGLInterface* interface = this->glInterface();
@@ -1135,26 +1086,30 @@ bool GrGLGpu::uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight
GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ROW_LENGTH, rowLength));
restoreGLRowLength = true;
}
- } else if (trimRowBytes != rowBytes || swFlipY) {
- // copy data into our new storage, skipping the trailing bytes
- const char* src = (const char*)texelsShallowCopy[currentMipLevel].fPixels;
- if (swFlipY && currentHeight >= 1) {
- src += (currentHeight - 1) * rowBytes;
- }
- char* dst = buffer + individual_mip_offsets[currentMipLevel];
- for (int y = 0; y < currentHeight; y++) {
- memcpy(dst, src, trimRowBytes);
- if (swFlipY) {
- src -= rowBytes;
- } else {
- src += rowBytes;
+ } else if (kTransfer_UploadType != uploadType) {
+ if (trimRowBytes != rowBytes || swFlipY) {
+ // copy data into our new storage, skipping the trailing bytes
+ const char* src = (const char*)texelsShallowCopy[currentMipLevel].fPixels;
+ if (swFlipY && currentHeight >= 1) {
+ src += (currentHeight - 1) * rowBytes;
+ }
+ char* dst = buffer + individual_mip_offsets[currentMipLevel];
+ for (int y = 0; y < currentHeight; y++) {
+ memcpy(dst, src, trimRowBytes);
+ if (swFlipY) {
+ src -= rowBytes;
+ } else {
+ src += rowBytes;
+ }
+ dst += trimRowBytes;
}
- dst += trimRowBytes;
+ // now point data to our copied version
+ texelsShallowCopy[currentMipLevel].fPixels = buffer +
+ individual_mip_offsets[currentMipLevel];
+ texelsShallowCopy[currentMipLevel].fRowBytes = trimRowBytes;
}
- // now point data to our copied version
- texelsShallowCopy[currentMipLevel].fPixels = buffer +
- individual_mip_offsets[currentMipLevel];
- texelsShallowCopy[currentMipLevel].fRowBytes = trimRowBytes;
+ } else {
+ return false;
}
}
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 5897f5dae5..80a12eb7cc 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -247,7 +247,7 @@ private:
GrPixelConfig config,
const SkTArray<GrMipLevel>& texels) override;
- bool onTransferPixels(GrTexture*,
+ bool onTransferPixels(GrSurface*,
int left, int top, int width, int height,
GrPixelConfig config, GrBuffer* transferBuffer,
size_t offset, size_t rowBytes) override;
@@ -373,8 +373,9 @@ private:
// helper for onCreateTexture and writeTexturePixels
enum UploadType {
- kNewTexture_UploadType, // we are creating a new texture
- kWrite_UploadType, // we are using TexSubImage2D to copy data to an existing texture
+ kNewTexture_UploadType, // we are creating a new texture
+ kWrite_UploadType, // we are using TexSubImage2D to copy data to an existing texture
+ kTransfer_UploadType, // we are using a transfer buffer to copy data
};
bool uploadTexData(GrPixelConfig texConfig, int texWidth, int texHeight,
GrSurfaceOrigin texOrigin, GrGLenum target, UploadType uploadType, int left,
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index d237632d9e..b10e9ed59d 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -301,13 +301,11 @@ GrBuffer* GrVkGpu::onCreateBuffer(size_t size, GrBufferType type, GrAccessPatter
buff = GrVkIndexBuffer::Create(this, size, kDynamic_GrAccessPattern == accessPattern);
break;
case kXferCpuToGpu_GrBufferType:
- SkASSERT(kDynamic_GrAccessPattern == accessPattern ||
- kStream_GrAccessPattern == accessPattern);
+ SkASSERT(kStream_GrAccessPattern == accessPattern);
buff = GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyRead_Type);
break;
case kXferGpuToCpu_GrBufferType:
- SkASSERT(kDynamic_GrAccessPattern == accessPattern ||
- kStream_GrAccessPattern == accessPattern);
+ SkASSERT(kStream_GrAccessPattern == accessPattern);
buff = GrVkTransferBuffer::Create(this, size, GrVkBuffer::kCopyWrite_Type);
break;
case kTexel_GrBufferType:
@@ -422,62 +420,6 @@ bool GrVkGpu::onWritePixels(GrSurface* surface,
return success;
}
-bool GrVkGpu::onTransferPixels(GrTexture* texture,
- int left, int top, int width, int height,
- GrPixelConfig config, GrBuffer* transferBuffer,
- size_t bufferOffset, size_t rowBytes) {
- // Vulkan only supports 4-byte aligned offsets
- if (SkToBool(bufferOffset & 0x2)) {
- return false;
- }
- GrVkTexture* vkTex = static_cast<GrVkTexture*>(texture);
- if (!vkTex) {
- return false;
- }
- GrVkTransferBuffer* vkBuffer = static_cast<GrVkTransferBuffer*>(transferBuffer);
- if (!vkBuffer) {
- return false;
- }
-
- // We assume Vulkan doesn't do sRGB <-> linear conversions when reading and writing pixels.
- if (GrPixelConfigIsSRGB(texture->config()) != GrPixelConfigIsSRGB(config)) {
- return false;
- }
-
- size_t bpp = GrBytesPerPixel(config);
- if (rowBytes == 0) {
- rowBytes = bpp*width;
- }
-
- // Set up copy region
- VkBufferImageCopy region;
- memset(&region, 0, sizeof(VkBufferImageCopy));
- region.bufferOffset = bufferOffset;
- 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 };
-
- // Change layout of our target so it can be copied to
- vkTex->setImageLayout(this,
- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
- VK_ACCESS_TRANSFER_WRITE_BIT,
- VK_PIPELINE_STAGE_TRANSFER_BIT,
- false);
-
- // Copy the buffer to the image
- fCurrentCmdBuffer->copyBufferToImage(this,
- vkBuffer,
- vkTex,
- VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
- 1,
- &region);
-
- vkTex->texturePriv().dirtyMipMaps(true);
- return true;
-}
-
void GrVkGpu::resolveImage(GrSurface* dst, GrVkRenderTarget* src, const SkIRect& srcRect,
const SkIPoint& dstPoint) {
SkASSERT(dst);
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 8a3fb09296..236b34a3c1 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -203,10 +203,10 @@ private:
int left, int top, int width, int height,
GrPixelConfig config, const SkTArray<GrMipLevel>&) override;
- bool onTransferPixels(GrTexture*,
+ bool onTransferPixels(GrSurface*,
int left, int top, int width, int height,
GrPixelConfig config, GrBuffer* transferBuffer,
- size_t offset, size_t rowBytes) override;
+ size_t offset, size_t rowBytes) override { return false; }
// Ends and submits the current command buffer to the queue and then creates a new command
// buffer and begins it. If sync is set to kForce_SyncQueue, the function will wait for all
diff --git a/tests/TransferPixelsTest.cpp b/tests/TransferPixelsTest.cpp
deleted file mode 100755
index 2e75decb47..0000000000
--- a/tests/TransferPixelsTest.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-// This is a GPU-backend specific test. It relies on static intializers to work
-
-#include "SkTypes.h"
-
-#if SK_SUPPORT_GPU && SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
-
-#include "GrContextFactory.h"
-#include "GrContextPriv.h"
-#include "GrGpu.h"
-#include "GrResourceProvider.h"
-#include "GrSurfaceProxy.h"
-#include "GrTexture.h"
-#include "GrTest.h"
-#include "SkGr.h"
-#include "SkSurface.h"
-#include "Test.h"
-
-using sk_gpu_test::GrContextFactory;
-
-void fill_transfer_data(int left, int top, int width, int height, int bufferWidth,
- GrColor* data) {
-
- // build red-green gradient
- for (int j = top; j < top + height; ++j) {
- for (int i = left; i < left + width; ++i) {
- unsigned int red = (unsigned int)(256.f*((i - left) / (float)width));
- unsigned int green = (unsigned int)(256.f*((j - top) / (float)height));
- data[i + j*bufferWidth] = GrColorPackRGBA(red - (red>>8),
- green - (green>>8), 0xff, 0xff);
- }
- }
-}
-
-bool does_full_buffer_contain_correct_values(GrColor* srcBuffer,
- GrColor* dstBuffer,
- int width,
- int height,
- int bufferWidth,
- int bufferHeight,
- GrSurfaceOrigin origin) {
- GrColor* srcPtr = srcBuffer;
- bool bottomUp = SkToBool(kBottomLeft_GrSurfaceOrigin == origin);
- GrColor* dstPtr = bottomUp ? dstBuffer + bufferWidth*(bufferHeight-1) : dstBuffer;
- int dstIncrement = bottomUp ? -bufferWidth : +bufferWidth;
-
- for (int j = 0; j < height; ++j) {
- for (int i = 0; i < width; ++i) {
- if (srcPtr[i] != dstPtr[i]) {
- return false;
- }
- }
- srcPtr += bufferWidth;
- dstPtr += dstIncrement;
- }
- return true;
-}
-
-void basic_transfer_test(skiatest::Reporter* reporter, GrContext* context, GrPixelConfig config,
- GrSurfaceOrigin origin, bool renderTarget) {
- // set up the data
- const int kTextureWidth = 16;
- const int kTextureHeight = 16;
- const int kBufferWidth = 20;
- const int kBufferHeight = 16;
- size_t rowBytes = kBufferWidth * sizeof(GrColor);
- SkAutoTMalloc<GrColor> srcBuffer(kBufferWidth*kBufferHeight);
- SkAutoTMalloc<GrColor> dstBuffer(kBufferWidth*kBufferHeight);
-
- fill_transfer_data(0, 0, kTextureWidth, kTextureHeight, kBufferWidth, srcBuffer.get());
-
- // create and fill transfer buffer
- size_t size = GrBytesPerPixel(config)*kBufferWidth*kBufferWidth;
- uint32_t bufferFlags = GrResourceProvider::kNoPendingIO_Flag;
- GrBuffer* buffer = context->resourceProvider()->createBuffer(size,
- kXferCpuToGpu_GrBufferType,
- kDynamic_GrAccessPattern,
- bufferFlags);
- void* data = buffer->map();
- memcpy(data, srcBuffer.get(), size);
- buffer->unmap();
-
- // create texture
- GrSurfaceDesc desc;
- desc.fConfig = config;
- desc.fFlags = renderTarget ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
- desc.fOrigin = origin;
- desc.fWidth = kTextureWidth;
- desc.fHeight = kTextureHeight;
- desc.fSampleCnt = 0;
- sk_sp<GrTexture> tex = context->resourceProvider()->createTexture(desc, SkBudgeted::kNo);
-
- //////////////////////////
- // transfer full data
-
- bool result;
- result = context->getGpu()->transferPixels(tex.get(), 0, 0, kTextureWidth, kTextureHeight,
- config, buffer, 0, rowBytes);
- REPORTER_ASSERT(reporter, result);
-
- result = context->getGpu()->readPixels(tex.get(), 0, 0, kTextureWidth, kTextureHeight, config,
- dstBuffer.get(), rowBytes);
- REPORTER_ASSERT(reporter, result);
- REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_values(srcBuffer,
- dstBuffer,
- kTextureWidth,
- kTextureHeight,
- kBufferWidth,
- kBufferHeight,
- origin));
- //////////////////////////
- // transfer partial data
-
- const int kLeft = 2;
- const int kTop = 10;
- const int kWidth = 10;
- const int kHeight = 2;
-
- // change color of subrectangle
- fill_transfer_data(kLeft, kTop, kWidth, kHeight, kBufferWidth, srcBuffer.get());
- data = buffer->map();
- memcpy(data, srcBuffer.get(), size);
- buffer->unmap();
-
- size_t offset = sizeof(GrColor)*(kTop*kBufferWidth + kLeft);
- result = context->getGpu()->transferPixels(tex.get(), kLeft, kTop, kWidth, kHeight, config,
- buffer, offset, rowBytes);
- REPORTER_ASSERT(reporter, result);
-
- memset(dstBuffer, 0, kWidth*kHeight*sizeof(GrColor));
-
- result = context->getGpu()->readPixels(tex.get(), 0, 0, kTextureWidth, kTextureHeight, config,
- dstBuffer.get(), rowBytes);
- REPORTER_ASSERT(reporter, result);
-
- REPORTER_ASSERT(reporter, does_full_buffer_contain_correct_values(srcBuffer,
- dstBuffer,
- kTextureWidth,
- kTextureHeight,
- kBufferWidth,
- kBufferHeight,
- origin));
-}
-
-DEF_GPUTEST_FOR_RENDERING_CONTEXTS(TransferPixelsTest, reporter, ctxInfo) {
- // RGBA
- basic_transfer_test(reporter, ctxInfo.grContext(), kRGBA_8888_GrPixelConfig,
- kTopLeft_GrSurfaceOrigin, false);
- basic_transfer_test(reporter, ctxInfo.grContext(), kRGBA_8888_GrPixelConfig,
- kTopLeft_GrSurfaceOrigin, true);
- basic_transfer_test(reporter, ctxInfo.grContext(), kRGBA_8888_GrPixelConfig,
- kBottomLeft_GrSurfaceOrigin, false);
- basic_transfer_test(reporter, ctxInfo.grContext(), kRGBA_8888_GrPixelConfig,
- kBottomLeft_GrSurfaceOrigin, true);
-
- // BGRA
- basic_transfer_test(reporter, ctxInfo.grContext(), kBGRA_8888_GrPixelConfig,
- kTopLeft_GrSurfaceOrigin, false);
- basic_transfer_test(reporter, ctxInfo.grContext(), kBGRA_8888_GrPixelConfig,
- kTopLeft_GrSurfaceOrigin, true);
- basic_transfer_test(reporter, ctxInfo.grContext(), kBGRA_8888_GrPixelConfig,
- kBottomLeft_GrSurfaceOrigin, false);
- basic_transfer_test(reporter, ctxInfo.grContext(), kBGRA_8888_GrPixelConfig,
- kBottomLeft_GrSurfaceOrigin, true);
-}
-
-#endif
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
index 301ba6709b..93e5f6e3b9 100644
--- a/tools/gpu/GrTest.cpp
+++ b/tools/gpu/GrTest.cpp
@@ -402,7 +402,7 @@ private:
return false;
}
- bool onTransferPixels(GrTexture* texture,
+ bool onTransferPixels(GrSurface* surface,
int left, int top, int width, int height,
GrPixelConfig config, GrBuffer* transferBuffer,
size_t offset, size_t rowBytes) override {