diff options
author | Jim Van Verth <jvanverth@google.com> | 2017-06-21 15:55:46 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-06-22 13:14:01 +0000 |
commit | 2e5eaf022e9389b1382cc856fcd7a8e90a078e13 (patch) | |
tree | 99948f1cd1d90d74538e17c972f102268a9e64be /tests/TransferPixelsTest.cpp | |
parent | 222958d5cbd46af9e643eb77186efceb176dd95d (diff) |
Revert "Revert "Clean up onTransferPixels""
Bug: skia:5126
Change-Id: Ia1eaef56cca266ad4c413e711e63646e913222be
Reviewed-on: https://skia-review.googlesource.com/20445
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Diffstat (limited to 'tests/TransferPixelsTest.cpp')
-rwxr-xr-x | tests/TransferPixelsTest.cpp | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/tests/TransferPixelsTest.cpp b/tests/TransferPixelsTest.cpp new file mode 100755 index 0000000000..3b221ee531 --- /dev/null +++ b/tests/TransferPixelsTest.cpp @@ -0,0 +1,177 @@ +/* + * 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 + +#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 = rowBytes*kBufferHeight; + uint32_t bufferFlags = GrResourceProvider::kNoPendingIO_Flag; + sk_sp<GrBuffer> buffer(context->resourceProvider()->createBuffer(size, + kXferCpuToGpu_GrBufferType, + kDynamic_GrAccessPattern, + bufferFlags)); + if (!buffer) { + return; + } + + 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.get(), 0, rowBytes); + REPORTER_ASSERT(reporter, result); + + memset(dstBuffer.get(), 0xCDCD, size); + 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.get(), offset, rowBytes); + REPORTER_ASSERT(reporter, result); + + memset(dstBuffer.get(), 0xCDCD, size); + 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 |