| Index: components/display_compositor/yuv_readback_unittest.cc
|
| diff --git a/components/display_compositor/yuv_readback_unittest.cc b/components/display_compositor/yuv_readback_unittest.cc
|
| deleted file mode 100644
|
| index 15430ab174935257a6e7edbc52fc0b669d9e460e..0000000000000000000000000000000000000000
|
| --- a/components/display_compositor/yuv_readback_unittest.cc
|
| +++ /dev/null
|
| @@ -1,554 +0,0 @@
|
| -// Copyright 2016 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "base/json/json_reader.h"
|
| -#include "base/memory/ref_counted_memory.h"
|
| -#include "base/run_loop.h"
|
| -#include "base/strings/stringprintf.h"
|
| -#include "base/test/launcher/unit_test_launcher.h"
|
| -#include "base/test/test_suite.h"
|
| -#include "components/display_compositor/gl_helper.h"
|
| -#include "gpu/command_buffer/client/gl_in_process_context.h"
|
| -#include "gpu/command_buffer/client/gles2_implementation.h"
|
| -#include "media/base/video_frame.h"
|
| -#include "media/base/video_util.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -#include "third_party/skia/include/core/SkBitmap.h"
|
| -#include "ui/gl/gl_implementation.h"
|
| -
|
| -namespace display_compositor {
|
| -
|
| -namespace {
|
| -int kYUVReadbackSizes[] = {2, 4, 14};
|
| -}
|
| -
|
| -class YUVReadbackTest : public testing::Test {
|
| - protected:
|
| - void SetUp() override {
|
| - gpu::gles2::ContextCreationAttribHelper attributes;
|
| - attributes.alpha_size = 8;
|
| - attributes.depth_size = 24;
|
| - attributes.red_size = 8;
|
| - attributes.green_size = 8;
|
| - attributes.blue_size = 8;
|
| - attributes.stencil_size = 8;
|
| - attributes.samples = 4;
|
| - attributes.sample_buffers = 1;
|
| - attributes.bind_generates_resource = false;
|
| -
|
| - context_.reset(gpu::GLInProcessContext::Create(
|
| - nullptr, /* service */
|
| - nullptr, /* surface */
|
| - true, /* offscreen */
|
| - gfx::kNullAcceleratedWidget, /* window */
|
| - gfx::Size(1, 1), /* size */
|
| - nullptr, /* share_context */
|
| - attributes, gfx::PreferDiscreteGpu,
|
| - ::gpu::GLInProcessContextSharedMemoryLimits(),
|
| - nullptr, /* gpu_memory_buffer_manager */
|
| - nullptr /* image_factory */));
|
| - gl_ = context_->GetImplementation();
|
| - gpu::ContextSupport* support = context_->GetImplementation();
|
| -
|
| - helper_.reset(new display_compositor::GLHelper(gl_, support));
|
| - }
|
| -
|
| - void TearDown() override {
|
| - helper_.reset(NULL);
|
| - context_.reset(NULL);
|
| - }
|
| -
|
| - void StartTracing(const std::string& filter) {
|
| - base::trace_event::TraceLog::GetInstance()->SetEnabled(
|
| - base::trace_event::TraceConfig(filter,
|
| - base::trace_event::RECORD_UNTIL_FULL),
|
| - base::trace_event::TraceLog::RECORDING_MODE);
|
| - }
|
| -
|
| - static void TraceDataCB(
|
| - const base::Callback<void()>& callback,
|
| - std::string* output,
|
| - const scoped_refptr<base::RefCountedString>& json_events_str,
|
| - bool has_more_events) {
|
| - if (output->size() > 1 && !json_events_str->data().empty()) {
|
| - output->append(",");
|
| - }
|
| - output->append(json_events_str->data());
|
| - if (!has_more_events) {
|
| - callback.Run();
|
| - }
|
| - }
|
| -
|
| - // End tracing, return tracing data in a simple map
|
| - // of event name->counts.
|
| - void EndTracing(std::map<std::string, int>* event_counts) {
|
| - std::string json_data = "[";
|
| - base::trace_event::TraceLog::GetInstance()->SetDisabled();
|
| - base::RunLoop run_loop;
|
| - base::trace_event::TraceLog::GetInstance()->Flush(
|
| - base::Bind(&YUVReadbackTest::TraceDataCB, run_loop.QuitClosure(),
|
| - base::Unretained(&json_data)));
|
| - run_loop.Run();
|
| - json_data.append("]");
|
| -
|
| - std::string error_msg;
|
| - std::unique_ptr<base::Value> trace_data =
|
| - base::JSONReader::ReadAndReturnError(json_data, 0, NULL, &error_msg);
|
| - CHECK(trace_data) << "JSON parsing failed (" << error_msg
|
| - << ") JSON data:" << std::endl
|
| - << json_data;
|
| -
|
| - base::ListValue* list;
|
| - CHECK(trace_data->GetAsList(&list));
|
| - for (size_t i = 0; i < list->GetSize(); i++) {
|
| - base::Value* item = NULL;
|
| - if (list->Get(i, &item)) {
|
| - base::DictionaryValue* dict;
|
| - CHECK(item->GetAsDictionary(&dict));
|
| - std::string name;
|
| - CHECK(dict->GetString("name", &name));
|
| - std::string trace_type;
|
| - CHECK(dict->GetString("ph", &trace_type));
|
| - // Count all except END traces, as they come in BEGIN/END pairs.
|
| - if (trace_type != "E" && trace_type != "e")
|
| - (*event_counts)[name]++;
|
| - VLOG(1) << "trace name: " << name;
|
| - }
|
| - }
|
| - }
|
| -
|
| - // Look up a single channel value. Works for 4-channel and single channel
|
| - // bitmaps. Clamp x/y.
|
| - int Channel(SkBitmap* pixels, int x, int y, int c) {
|
| - if (pixels->bytesPerPixel() == 4) {
|
| - uint32_t* data =
|
| - pixels->getAddr32(std::max(0, std::min(x, pixels->width() - 1)),
|
| - std::max(0, std::min(y, pixels->height() - 1)));
|
| - return (*data) >> (c * 8) & 0xff;
|
| - } else {
|
| - DCHECK_EQ(pixels->bytesPerPixel(), 1);
|
| - DCHECK_EQ(c, 0);
|
| - return *pixels->getAddr8(std::max(0, std::min(x, pixels->width() - 1)),
|
| - std::max(0, std::min(y, pixels->height() - 1)));
|
| - }
|
| - }
|
| -
|
| - // Set a single channel value. Works for 4-channel and single channel
|
| - // bitmaps. Clamp x/y.
|
| - void SetChannel(SkBitmap* pixels, int x, int y, int c, int v) {
|
| - DCHECK_GE(x, 0);
|
| - DCHECK_GE(y, 0);
|
| - DCHECK_LT(x, pixels->width());
|
| - DCHECK_LT(y, pixels->height());
|
| - if (pixels->bytesPerPixel() == 4) {
|
| - uint32_t* data = pixels->getAddr32(x, y);
|
| - v = std::max(0, std::min(v, 255));
|
| - *data = (*data & ~(0xffu << (c * 8))) | (v << (c * 8));
|
| - } else {
|
| - DCHECK_EQ(pixels->bytesPerPixel(), 1);
|
| - DCHECK_EQ(c, 0);
|
| - uint8_t* data = pixels->getAddr8(x, y);
|
| - v = std::max(0, std::min(v, 255));
|
| - *data = v;
|
| - }
|
| - }
|
| -
|
| - // Print all the R, G, B or A values from an SkBitmap in a
|
| - // human-readable format.
|
| - void PrintChannel(SkBitmap* pixels, int c) {
|
| - for (int y = 0; y < pixels->height(); y++) {
|
| - std::string formatted;
|
| - for (int x = 0; x < pixels->width(); x++) {
|
| - formatted.append(base::StringPrintf("%3d, ", Channel(pixels, x, y, c)));
|
| - }
|
| - LOG(ERROR) << formatted;
|
| - }
|
| - }
|
| -
|
| - // Get a single R, G, B or A value as a float.
|
| - float ChannelAsFloat(SkBitmap* pixels, int x, int y, int c) {
|
| - return Channel(pixels, x, y, c) / 255.0;
|
| - }
|
| -
|
| - // Works like a GL_LINEAR lookup on an SkBitmap.
|
| - float Bilinear(SkBitmap* pixels, float x, float y, int c) {
|
| - x -= 0.5;
|
| - y -= 0.5;
|
| - int base_x = static_cast<int>(floorf(x));
|
| - int base_y = static_cast<int>(floorf(y));
|
| - x -= base_x;
|
| - y -= base_y;
|
| - return (ChannelAsFloat(pixels, base_x, base_y, c) * (1 - x) * (1 - y) +
|
| - ChannelAsFloat(pixels, base_x + 1, base_y, c) * x * (1 - y) +
|
| - ChannelAsFloat(pixels, base_x, base_y + 1, c) * (1 - x) * y +
|
| - ChannelAsFloat(pixels, base_x + 1, base_y + 1, c) * x * y);
|
| - }
|
| -
|
| - void FlipSKBitmap(SkBitmap* bitmap) {
|
| - int bpp = bitmap->bytesPerPixel();
|
| - DCHECK(bpp == 4 || bpp == 1);
|
| - int top_line = 0;
|
| - int bottom_line = bitmap->height() - 1;
|
| - while (top_line < bottom_line) {
|
| - for (int x = 0; x < bitmap->width(); x++) {
|
| - bpp == 4 ? std::swap(*bitmap->getAddr32(x, top_line),
|
| - *bitmap->getAddr32(x, bottom_line))
|
| - : std::swap(*bitmap->getAddr8(x, top_line),
|
| - *bitmap->getAddr8(x, bottom_line));
|
| - }
|
| - top_line++;
|
| - bottom_line--;
|
| - }
|
| - }
|
| -
|
| - // Note: Left/Right means Top/Bottom when used for Y dimension.
|
| - enum Margin {
|
| - MarginLeft,
|
| - MarginMiddle,
|
| - MarginRight,
|
| - MarginInvalid,
|
| - };
|
| -
|
| - static Margin NextMargin(Margin m) {
|
| - switch (m) {
|
| - case MarginLeft:
|
| - return MarginMiddle;
|
| - case MarginMiddle:
|
| - return MarginRight;
|
| - case MarginRight:
|
| - return MarginInvalid;
|
| - default:
|
| - return MarginInvalid;
|
| - }
|
| - }
|
| -
|
| - int compute_margin(int insize, int outsize, Margin m) {
|
| - int available = outsize - insize;
|
| - switch (m) {
|
| - default:
|
| - EXPECT_TRUE(false) << "This should not happen.";
|
| - return 0;
|
| - case MarginLeft:
|
| - return 0;
|
| - case MarginMiddle:
|
| - return (available / 2) & ~1;
|
| - case MarginRight:
|
| - return available;
|
| - }
|
| - }
|
| -
|
| - // Convert 0.0 - 1.0 to 0 - 255
|
| - int float_to_byte(float v) {
|
| - int ret = static_cast<int>(floorf(v * 255.0f + 0.5f));
|
| - if (ret < 0) {
|
| - return 0;
|
| - }
|
| - if (ret > 255) {
|
| - return 255;
|
| - }
|
| - return ret;
|
| - }
|
| -
|
| - static void callcallback(const base::Callback<void()>& callback,
|
| - bool result) {
|
| - callback.Run();
|
| - }
|
| -
|
| - void PrintPlane(unsigned char* plane, int xsize, int stride, int ysize) {
|
| - for (int y = 0; y < ysize; y++) {
|
| - std::string formatted;
|
| - for (int x = 0; x < xsize; x++) {
|
| - formatted.append(base::StringPrintf("%3d, ", plane[y * stride + x]));
|
| - }
|
| - LOG(ERROR) << formatted << " (" << (plane + y * stride) << ")";
|
| - }
|
| - }
|
| -
|
| - // Compare two planes make sure that each component of each pixel
|
| - // is no more than |maxdiff| apart.
|
| - void ComparePlane(unsigned char* truth,
|
| - int truth_stride,
|
| - unsigned char* other,
|
| - int other_stride,
|
| - int maxdiff,
|
| - int xsize,
|
| - int ysize,
|
| - SkBitmap* source,
|
| - std::string message) {
|
| - for (int x = 0; x < xsize; x++) {
|
| - for (int y = 0; y < ysize; y++) {
|
| - int a = other[y * other_stride + x];
|
| - int b = truth[y * truth_stride + x];
|
| - EXPECT_NEAR(a, b, maxdiff) << " x=" << x << " y=" << y << " "
|
| - << message;
|
| - if (std::abs(a - b) > maxdiff) {
|
| - LOG(ERROR) << "-------expected--------";
|
| - PrintPlane(truth, xsize, truth_stride, ysize);
|
| - LOG(ERROR) << "-------actual--------";
|
| - PrintPlane(other, xsize, other_stride, ysize);
|
| - if (source) {
|
| - LOG(ERROR) << "-------before yuv conversion: red--------";
|
| - PrintChannel(source, 0);
|
| - LOG(ERROR) << "-------before yuv conversion: green------";
|
| - PrintChannel(source, 1);
|
| - LOG(ERROR) << "-------before yuv conversion: blue-------";
|
| - PrintChannel(source, 2);
|
| - }
|
| - return;
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| - // YUV readback test. Create a test pattern, convert to YUV
|
| - // with reference implementation and compare to what gl_helper
|
| - // returns.
|
| - void TestYUVReadback(int xsize,
|
| - int ysize,
|
| - int output_xsize,
|
| - int output_ysize,
|
| - int xmargin,
|
| - int ymargin,
|
| - int test_pattern,
|
| - bool flip,
|
| - bool use_mrt,
|
| - display_compositor::GLHelper::ScalerQuality quality) {
|
| - GLuint src_texture;
|
| - gl_->GenTextures(1, &src_texture);
|
| - SkBitmap input_pixels;
|
| - input_pixels.allocN32Pixels(xsize, ysize);
|
| -
|
| - for (int x = 0; x < xsize; ++x) {
|
| - for (int y = 0; y < ysize; ++y) {
|
| - switch (test_pattern) {
|
| - case 0: // Smooth test pattern
|
| - SetChannel(&input_pixels, x, y, 0, x * 10);
|
| - SetChannel(&input_pixels, x, y, 1, y * 10);
|
| - SetChannel(&input_pixels, x, y, 2, (x + y) * 10);
|
| - SetChannel(&input_pixels, x, y, 3, 255);
|
| - break;
|
| - case 1: // Small blocks
|
| - SetChannel(&input_pixels, x, y, 0, x & 1 ? 255 : 0);
|
| - SetChannel(&input_pixels, x, y, 1, y & 1 ? 255 : 0);
|
| - SetChannel(&input_pixels, x, y, 2, (x + y) & 1 ? 255 : 0);
|
| - SetChannel(&input_pixels, x, y, 3, 255);
|
| - break;
|
| - case 2: // Medium blocks
|
| - SetChannel(&input_pixels, x, y, 0, 10 + x / 2 * 50);
|
| - SetChannel(&input_pixels, x, y, 1, 10 + y / 3 * 50);
|
| - SetChannel(&input_pixels, x, y, 2, (x + y) / 5 * 50 + 5);
|
| - SetChannel(&input_pixels, x, y, 3, 255);
|
| - break;
|
| - }
|
| - }
|
| - }
|
| -
|
| - gl_->BindTexture(GL_TEXTURE_2D, src_texture);
|
| - gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, xsize, ysize, 0, GL_RGBA,
|
| - GL_UNSIGNED_BYTE, input_pixels.getPixels());
|
| -
|
| - gpu::Mailbox mailbox;
|
| - gl_->GenMailboxCHROMIUM(mailbox.name);
|
| - EXPECT_FALSE(mailbox.IsZero());
|
| - gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
|
| - const GLuint64 fence_sync = gl_->InsertFenceSyncCHROMIUM();
|
| - gl_->ShallowFlushCHROMIUM();
|
| -
|
| - gpu::SyncToken sync_token;
|
| - gl_->GenSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
|
| -
|
| - std::string message = base::StringPrintf(
|
| - "input size: %dx%d "
|
| - "output size: %dx%d "
|
| - "margin: %dx%d "
|
| - "pattern: %d %s %s",
|
| - xsize, ysize, output_xsize, output_ysize, xmargin, ymargin,
|
| - test_pattern, flip ? "flip" : "noflip", flip ? "mrt" : "nomrt");
|
| - std::unique_ptr<ReadbackYUVInterface> yuv_reader(
|
| - helper_->CreateReadbackPipelineYUV(
|
| - quality, gfx::Size(xsize, ysize), gfx::Rect(0, 0, xsize, ysize),
|
| - gfx::Size(xsize, ysize), flip, use_mrt));
|
| -
|
| - scoped_refptr<media::VideoFrame> output_frame =
|
| - media::VideoFrame::CreateFrame(
|
| - media::PIXEL_FORMAT_YV12,
|
| - // The coded size of the output frame is rounded up to the next
|
| - // 16-byte boundary. This tests that the readback is being
|
| - // positioned inside the frame's visible region, and not dependent
|
| - // on its coded size.
|
| - gfx::Size((output_xsize + 15) & ~15, (output_ysize + 15) & ~15),
|
| - gfx::Rect(0, 0, output_xsize, output_ysize),
|
| - gfx::Size(output_xsize, output_ysize),
|
| - base::TimeDelta::FromSeconds(0));
|
| - scoped_refptr<media::VideoFrame> truth_frame =
|
| - media::VideoFrame::CreateFrame(
|
| - media::PIXEL_FORMAT_YV12, gfx::Size(output_xsize, output_ysize),
|
| - gfx::Rect(0, 0, output_xsize, output_ysize),
|
| - gfx::Size(output_xsize, output_ysize),
|
| - base::TimeDelta::FromSeconds(0));
|
| -
|
| - base::RunLoop run_loop;
|
| - yuv_reader->ReadbackYUV(mailbox, sync_token, output_frame->visible_rect(),
|
| - output_frame->stride(media::VideoFrame::kYPlane),
|
| - output_frame->data(media::VideoFrame::kYPlane),
|
| - output_frame->stride(media::VideoFrame::kUPlane),
|
| - output_frame->data(media::VideoFrame::kUPlane),
|
| - output_frame->stride(media::VideoFrame::kVPlane),
|
| - output_frame->data(media::VideoFrame::kVPlane),
|
| - gfx::Point(xmargin, ymargin),
|
| - base::Bind(&callcallback, run_loop.QuitClosure()));
|
| -
|
| - const gfx::Rect paste_rect(gfx::Point(xmargin, ymargin),
|
| - gfx::Size(xsize, ysize));
|
| - media::LetterboxYUV(output_frame.get(), paste_rect);
|
| - run_loop.Run();
|
| -
|
| - if (flip) {
|
| - FlipSKBitmap(&input_pixels);
|
| - }
|
| -
|
| - unsigned char* Y = truth_frame->visible_data(media::VideoFrame::kYPlane);
|
| - unsigned char* U = truth_frame->visible_data(media::VideoFrame::kUPlane);
|
| - unsigned char* V = truth_frame->visible_data(media::VideoFrame::kVPlane);
|
| - int32_t y_stride = truth_frame->stride(media::VideoFrame::kYPlane);
|
| - int32_t u_stride = truth_frame->stride(media::VideoFrame::kUPlane);
|
| - int32_t v_stride = truth_frame->stride(media::VideoFrame::kVPlane);
|
| - memset(Y, 0x00, y_stride * output_ysize);
|
| - memset(U, 0x80, u_stride * output_ysize / 2);
|
| - memset(V, 0x80, v_stride * output_ysize / 2);
|
| -
|
| - const float kRGBtoYColorWeights[] = {0.257f, 0.504f, 0.098f, 0.0625f};
|
| - const float kRGBtoUColorWeights[] = {-0.148f, -0.291f, 0.439f, 0.5f};
|
| - const float kRGBtoVColorWeights[] = {0.439f, -0.368f, -0.071f, 0.5f};
|
| -
|
| - for (int y = 0; y < ysize; y++) {
|
| - for (int x = 0; x < xsize; x++) {
|
| - Y[(y + ymargin) * y_stride + x + xmargin] = float_to_byte(
|
| - ChannelAsFloat(&input_pixels, x, y, 0) * kRGBtoYColorWeights[0] +
|
| - ChannelAsFloat(&input_pixels, x, y, 1) * kRGBtoYColorWeights[1] +
|
| - ChannelAsFloat(&input_pixels, x, y, 2) * kRGBtoYColorWeights[2] +
|
| - kRGBtoYColorWeights[3]);
|
| - }
|
| - }
|
| -
|
| - for (int y = 0; y < ysize / 2; y++) {
|
| - for (int x = 0; x < xsize / 2; x++) {
|
| - U[(y + ymargin / 2) * u_stride + x + xmargin / 2] =
|
| - float_to_byte(Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 0) *
|
| - kRGBtoUColorWeights[0] +
|
| - Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 1) *
|
| - kRGBtoUColorWeights[1] +
|
| - Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 2) *
|
| - kRGBtoUColorWeights[2] +
|
| - kRGBtoUColorWeights[3]);
|
| - V[(y + ymargin / 2) * v_stride + x + xmargin / 2] =
|
| - float_to_byte(Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 0) *
|
| - kRGBtoVColorWeights[0] +
|
| - Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 1) *
|
| - kRGBtoVColorWeights[1] +
|
| - Bilinear(&input_pixels, x * 2 + 1.0, y * 2 + 1.0, 2) *
|
| - kRGBtoVColorWeights[2] +
|
| - kRGBtoVColorWeights[3]);
|
| - }
|
| - }
|
| -
|
| - ComparePlane(
|
| - Y, y_stride, output_frame->visible_data(media::VideoFrame::kYPlane),
|
| - output_frame->stride(media::VideoFrame::kYPlane), 2, output_xsize,
|
| - output_ysize, &input_pixels, message + " Y plane");
|
| - ComparePlane(
|
| - U, u_stride, output_frame->visible_data(media::VideoFrame::kUPlane),
|
| - output_frame->stride(media::VideoFrame::kUPlane), 2, output_xsize / 2,
|
| - output_ysize / 2, &input_pixels, message + " U plane");
|
| - ComparePlane(
|
| - V, v_stride, output_frame->visible_data(media::VideoFrame::kVPlane),
|
| - output_frame->stride(media::VideoFrame::kVPlane), 2, output_xsize / 2,
|
| - output_ysize / 2, &input_pixels, message + " V plane");
|
| -
|
| - gl_->DeleteTextures(1, &src_texture);
|
| - }
|
| -
|
| - std::unique_ptr<gpu::GLInProcessContext> context_;
|
| - gpu::gles2::GLES2Interface* gl_;
|
| - std::unique_ptr<display_compositor::GLHelper> helper_;
|
| - gfx::DisableNullDrawGLBindings enable_pixel_output_;
|
| -};
|
| -
|
| -TEST_F(YUVReadbackTest, YUVReadbackOptTest) {
|
| - // This test uses the gpu.service/gpu_decoder tracing events to detect how
|
| - // many scaling passes are actually performed by the YUV readback pipeline.
|
| - StartTracing(TRACE_DISABLED_BY_DEFAULT(
|
| - "gpu.service") "," TRACE_DISABLED_BY_DEFAULT("gpu_decoder"));
|
| -
|
| - TestYUVReadback(800, 400, 800, 400, 0, 0, 1, false, true,
|
| - display_compositor::GLHelper::SCALER_QUALITY_FAST);
|
| -
|
| - std::map<std::string, int> event_counts;
|
| - EndTracing(&event_counts);
|
| - int draw_buffer_calls = event_counts["kDrawBuffersEXTImmediate"];
|
| - int draw_arrays_calls = event_counts["kDrawArrays"];
|
| - VLOG(1) << "Draw buffer calls: " << draw_buffer_calls;
|
| - VLOG(1) << "DrawArrays calls: " << draw_arrays_calls;
|
| -
|
| - if (draw_buffer_calls) {
|
| - // When using MRT, the YUV readback code should only
|
| - // execute two draw arrays, and scaling should be integrated
|
| - // into those two calls since we are using the FAST scalign
|
| - // quality.
|
| - EXPECT_EQ(2, draw_arrays_calls);
|
| - } else {
|
| - // When not using MRT, there are three passes for the YUV,
|
| - // and one for the scaling.
|
| - EXPECT_EQ(4, draw_arrays_calls);
|
| - }
|
| -}
|
| -
|
| -class YUVReadbackPixelTest
|
| - : public YUVReadbackTest,
|
| - public ::testing::WithParamInterface<
|
| - std::tr1::tuple<bool, bool, unsigned int, unsigned int>> {};
|
| -
|
| -TEST_P(YUVReadbackPixelTest, Test) {
|
| - bool flip = std::tr1::get<0>(GetParam());
|
| - bool use_mrt = std::tr1::get<1>(GetParam());
|
| - unsigned int x = std::tr1::get<2>(GetParam());
|
| - unsigned int y = std::tr1::get<3>(GetParam());
|
| -
|
| - for (unsigned int ox = x; ox < arraysize(kYUVReadbackSizes); ox++) {
|
| - for (unsigned int oy = y; oy < arraysize(kYUVReadbackSizes); oy++) {
|
| - // If output is a subsection of the destination frame, (letterbox)
|
| - // then try different variations of where the subsection goes.
|
| - for (Margin xm = x < ox ? MarginLeft : MarginRight; xm <= MarginRight;
|
| - xm = NextMargin(xm)) {
|
| - for (Margin ym = y < oy ? MarginLeft : MarginRight; ym <= MarginRight;
|
| - ym = NextMargin(ym)) {
|
| - for (int pattern = 0; pattern < 3; pattern++) {
|
| - TestYUVReadback(
|
| - kYUVReadbackSizes[x], kYUVReadbackSizes[y],
|
| - kYUVReadbackSizes[ox], kYUVReadbackSizes[oy],
|
| - compute_margin(kYUVReadbackSizes[x], kYUVReadbackSizes[ox], xm),
|
| - compute_margin(kYUVReadbackSizes[y], kYUVReadbackSizes[oy], ym),
|
| - pattern, flip, use_mrt,
|
| - display_compositor::GLHelper::SCALER_QUALITY_GOOD);
|
| - if (HasFailure()) {
|
| - return;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| -// First argument is intentionally empty.
|
| -INSTANTIATE_TEST_CASE_P(
|
| - ,
|
| - YUVReadbackPixelTest,
|
| - ::testing::Combine(
|
| - ::testing::Bool(),
|
| - ::testing::Bool(),
|
| - ::testing::Range<unsigned int>(0, arraysize(kYUVReadbackSizes)),
|
| - ::testing::Range<unsigned int>(0, arraysize(kYUVReadbackSizes))));
|
| -
|
| -} // namespace display_compositor
|
|
|