Revert "Clean up onTransferPixels"

This reverts commit f7037d003c.

Reason for revert: Issues on test bots.

Original change's description:
> Clean up onTransferPixels
> 
> Bug: skia:5126
> Change-Id: I323c50e7854744302007b4ae7bd25e5742c14cbc
> Reviewed-on: https://skia-review.googlesource.com/19055
> Commit-Queue: Jim Van Verth <jvanverth@google.com>
> Reviewed-by: Greg Daniel <egdaniel@google.com>

TBR=egdaniel@google.com,jvanverth@google.com,bsalomon@google.com,brianosman@google.com

Change-Id: I923fda4d5cd8c2896fb347f9b2695b7f83d9137b
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:5126
Reviewed-on: https://skia-review.googlesource.com/20444
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Jim Van Verth 2017-06-21 15:50:46 +00:00 committed by Skia Commit-Bot
parent f7037d003c
commit ce57552e11
11 changed files with 84 additions and 367 deletions

View File

@ -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",

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;
}
dst += trimRowBytes;
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;
}
// 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;
}
}

View File

@ -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,

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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 {