| Index: ppapi/native_client/tests/ppapi_browser/ppb_graphics2d/ppapi_ppb_graphics2d.cc
|
| ===================================================================
|
| --- ppapi/native_client/tests/ppapi_browser/ppb_graphics2d/ppapi_ppb_graphics2d.cc (revision 0)
|
| +++ ppapi/native_client/tests/ppapi_browser/ppb_graphics2d/ppapi_ppb_graphics2d.cc (revision 0)
|
| @@ -0,0 +1,553 @@
|
| +// Copyright (c) 2011 The Native Client Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +//
|
| +// Test cases for PPB_Graphics2D functions.
|
| +// As most of them return void, the test automatically confirms that
|
| +// there is no crash while requiring a visual inspection of the painted output.
|
| +
|
| +#include <string.h>
|
| +
|
| +#include "native_client/src/include/nacl_macros.h"
|
| +#include "native_client/src/shared/platform/nacl_check.h"
|
| +#include "native_client/tests/ppapi_test_lib/get_browser_interface.h"
|
| +#include "native_client/tests/ppapi_test_lib/test_interface.h"
|
| +#include "ppapi/c/dev/ppb_testing_dev.h"
|
| +#include "ppapi/c/pp_bool.h"
|
| +#include "ppapi/c/pp_errors.h"
|
| +#include "ppapi/c/pp_point.h"
|
| +#include "ppapi/c/pp_rect.h"
|
| +#include "ppapi/c/pp_size.h"
|
| +#include "ppapi/c/ppb_core.h"
|
| +#include "ppapi/c/ppb_graphics_2d.h"
|
| +#include "ppapi/c/ppb_image_data.h"
|
| +#include "ppapi/c/ppb_instance.h"
|
| +#include "ppapi/c/ppb_url_loader.h"
|
| +
|
| +namespace {
|
| +
|
| +const PP_Bool kAlwaysOpaque = PP_TRUE;
|
| +const PP_Bool kNotAlwaysOpaque = PP_FALSE;
|
| +const PP_Size kNegativeWidth = PP_MakeSize(-1, 1);
|
| +const PP_Size kNegativeHeight = PP_MakeSize(1, -1);
|
| +const PP_Size kZeroPixels = PP_MakeSize(0, 0);
|
| +const PP_Size kOnePixel = PP_MakeSize(1, 1);
|
| +const PP_Size k90x90 = PP_MakeSize(90, 90);
|
| +const PP_Size k60x60 = PP_MakeSize(60, 60);
|
| +const PP_Size k30x30 = PP_MakeSize(30, 30);
|
| +const PP_Size k2500x2500 = PP_MakeSize(2500, 2500);
|
| +const PP_Size k100000x100000 = PP_MakeSize(100000, 100000);
|
| +const PP_Point kOrigin = PP_MakePoint(0, 0);
|
| +const PP_Rect kBadRect = { PP_MakePoint(-1, -1), PP_MakeSize(-1, -1) };
|
| +const PP_Rect* kEntireImage = NULL;
|
| +const PP_Bool kInitToZero = PP_TRUE;
|
| +
|
| +// TODO(polina, nfullagar): allow specification of non-premultipled colors
|
| +// and provide alpha premultiplcation in FormatColor(). This will be required
|
| +// when future PPAPI pixel formats are extended to include non-premultipled
|
| +// or ignored alpha.
|
| +
|
| +struct ColorPremul { uint32_t A, R, G, B; }; // Use premultipled Alpha.
|
| +const ColorPremul kSheerRed = { 0x88, 0x88, 0x00, 0x00 };
|
| +const ColorPremul kSheerBlue = { 0x88, 0x00, 0x00, 0x88 };
|
| +const ColorPremul kSheerGray = { 0x77, 0x55, 0x55, 0x55 };
|
| +const ColorPremul kOpaqueGreen = { 0xFF, 0x00, 0xFF, 0x00 };
|
| +const ColorPremul kOpaqueBlack = { 0xFF, 0x00, 0x00, 0x00 };
|
| +const ColorPremul kOpaqueWhite = { 0xFF, 0xFF, 0xFF, 0xFF };
|
| +const ColorPremul kOpaqueYellow = { 0xFF, 0xFF, 0xFF, 0x00 };
|
| +const int kBytesPerPixel = sizeof(uint32_t); // 4 bytes for BGRA or RGBA.
|
| +
|
| +// Assumes premultipled Alpha.
|
| +uint32_t FormatColor(PP_ImageDataFormat format, ColorPremul color) {
|
| + if (format == PP_IMAGEDATAFORMAT_BGRA_PREMUL)
|
| + return (color.A << 24) | (color.R << 16) | (color.G << 8) | (color.B);
|
| + else if (format == PP_IMAGEDATAFORMAT_RGBA_PREMUL)
|
| + return (color.A << 24) | (color.B << 16) | (color.G << 8) | (color.R);
|
| + else
|
| + NACL_NOTREACHED();
|
| +}
|
| +
|
| +// Make graphics2d contexts for each test the same size, so we can layer
|
| +// the images without invalidating the previous ones.
|
| +PP_Resource CreateGraphics2D_90x90() {
|
| + PP_Resource graphics2d = PPBGraphics2D()->Create(
|
| + pp_instance(), &k90x90, kNotAlwaysOpaque);
|
| + CHECK(graphics2d != kInvalidResource);
|
| + PPBInstance()->BindGraphics(pp_instance(), graphics2d);
|
| + return graphics2d;
|
| +}
|
| +
|
| +PP_Resource CreateImageData(PP_Size size, ColorPremul pixel_color, void** bmp) {
|
| + PP_ImageDataFormat image_format = PPBImageData()->GetNativeImageDataFormat();
|
| + uint32_t formatted_pixel_color = FormatColor(image_format, pixel_color);
|
| + PP_Resource image_data = PPBImageData()->Create(
|
| + pp_instance(), image_format, &size, kInitToZero);
|
| + CHECK(image_data != kInvalidResource);
|
| + PP_ImageDataDesc image_desc;
|
| + CHECK(PPBImageData()->Describe(image_data, &image_desc) == PP_TRUE);
|
| + *bmp = NULL;
|
| + *bmp = PPBImageData()->Map(image_data);
|
| + CHECK(*bmp != NULL);
|
| + uint32_t* bmp_words = static_cast<uint32_t*>(*bmp);
|
| + int num_pixels = image_desc.stride / kBytesPerPixel * image_desc.size.height;
|
| + for (int i = 0; i < num_pixels; i++)
|
| + bmp_words[i] = formatted_pixel_color;
|
| + return image_data;
|
| +}
|
| +
|
| +PP_Resource CreateImageData(PP_Size size, ColorPremul pixel_color) {
|
| + void* bitmap = NULL;
|
| + return CreateImageData(size, pixel_color, &bitmap);
|
| +}
|
| +
|
| +struct FlushData {
|
| + FlushData(PP_Resource g, PP_Resource i) : graphics2d(g), image_data(i) {}
|
| + PP_Resource graphics2d;
|
| + PP_Resource image_data;
|
| +};
|
| +
|
| +void FlushCallback(void* user_data, int32_t result);
|
| +int g_expected_flush_calls = 0;
|
| +PP_CompletionCallback MakeTestableFlushCallback(const char* name,
|
| + PP_Resource graphics2d,
|
| + PP_Resource image_data,
|
| + int num_calls) {
|
| + g_expected_flush_calls = num_calls;
|
| + void* user_data = new FlushData(graphics2d, image_data);
|
| + return MakeTestableCompletionCallback(name, FlushCallback, user_data);
|
| +}
|
| +
|
| +void FlushCallback(void* user_data, int32_t result) {
|
| + --g_expected_flush_calls;
|
| + CHECK(g_expected_flush_calls >= 0);
|
| + CHECK(user_data != NULL);
|
| + CHECK(result == PP_OK);
|
| +
|
| + FlushData* data = static_cast<FlushData*>(user_data);
|
| + PP_Resource graphics2d = data->graphics2d;
|
| + PP_Resource image_data = data->image_data;
|
| + if (g_expected_flush_calls == 0) {
|
| + PPBCore()->ReleaseResource(graphics2d);
|
| + PPBCore()->ReleaseResource(image_data);
|
| + delete data;
|
| + } else {
|
| + PPBGraphics2D()->PaintImageData(graphics2d, image_data, &kOrigin, NULL);
|
| + PP_CompletionCallback cc = MakeTestableFlushCallback(
|
| + "FlushAnimationCallback",
|
| + graphics2d, image_data, g_expected_flush_calls);
|
| + CHECK(PP_OK_COMPLETIONPENDING == PPBGraphics2D()->Flush(graphics2d, cc));
|
| + }
|
| +}
|
| +
|
| +bool IsEqualSize(PP_Size size1, PP_Size size2) {
|
| + return (size1.width == size2.width && size1.height == size2.height);
|
| +}
|
| +
|
| +bool IsSquareOnScreen(PP_Resource graphics2d, PP_Point origin, PP_Size square,
|
| + ColorPremul color) {
|
| + PP_Size size;
|
| + PP_Bool dummy;
|
| + CHECK(PP_TRUE == PPBGraphics2D()->Describe(graphics2d, &size, &dummy));
|
| +
|
| + void* bitmap = NULL;
|
| + PP_Resource image = CreateImageData(size, kOpaqueBlack, &bitmap);
|
| +
|
| + PP_ImageDataDesc image_desc;
|
| + CHECK(PP_TRUE == PPBImageData()->Describe(image, &image_desc));
|
| + int32_t stride = image_desc.stride / kBytesPerPixel; // width + padding.
|
| + uint32_t expected_color = FormatColor(image_desc.format, color);
|
| + CHECK(origin.x >= 0 && origin.y >= 0 &&
|
| + (origin.x + square.width) <= stride &&
|
| + (origin.y + square.height) <= image_desc.size.height);
|
| +
|
| + CHECK(PP_TRUE == PPBTestingDev()->ReadImageData(graphics2d, image, &kOrigin));
|
| + bool found_error = false;
|
| + for (int y = origin.y; y < origin.y + square.height && !found_error; y++) {
|
| + for (int x = origin.x; x < origin.x + square.width && !found_error; x++) {
|
| + uint32_t pixel_color = static_cast<uint32_t*>(bitmap)[stride * y + x];
|
| + found_error = (pixel_color != expected_color);
|
| + }
|
| + }
|
| +
|
| + PPBCore()->ReleaseResource(image);
|
| + return !found_error;
|
| +}
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// Test Cases
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +// Tests PPB_Graphics2D::Create().
|
| +void TestCreate() {
|
| + PP_Resource graphics2d = kInvalidResource;
|
| + const PPB_Graphics2D* ppb = PPBGraphics2D();
|
| +
|
| + // Invalid instance and size -> invalid resource.
|
| + graphics2d = ppb->Create(kInvalidInstance, &k30x30, kAlwaysOpaque);
|
| + EXPECT(graphics2d == kInvalidResource);
|
| + graphics2d = ppb->Create(kInvalidInstance, &k30x30, kNotAlwaysOpaque);
|
| + EXPECT(graphics2d == kInvalidResource);
|
| + graphics2d = ppb->Create(kNotAnInstance, &k30x30, kAlwaysOpaque);
|
| + EXPECT(graphics2d == kInvalidResource);
|
| + graphics2d = ppb->Create(kNotAnInstance, &k30x30, kNotAlwaysOpaque);
|
| + EXPECT(graphics2d == kInvalidResource);
|
| + graphics2d = ppb->Create(pp_instance(), &k100000x100000, kAlwaysOpaque);
|
| + EXPECT(graphics2d == kInvalidResource);
|
| + graphics2d = ppb->Create(pp_instance(), &k100000x100000, kNotAlwaysOpaque);
|
| + EXPECT(graphics2d == kInvalidResource);
|
| + graphics2d = ppb->Create(pp_instance(), &kZeroPixels, kAlwaysOpaque);
|
| + EXPECT(graphics2d == kInvalidResource);
|
| + graphics2d = ppb->Create(pp_instance(), &kZeroPixels, kNotAlwaysOpaque);
|
| + EXPECT(graphics2d == kInvalidResource);
|
| + graphics2d = ppb->Create(pp_instance(), &kNegativeWidth, kAlwaysOpaque);
|
| + EXPECT(graphics2d == kInvalidResource);
|
| + graphics2d = ppb->Create(pp_instance(), &kNegativeHeight, kNotAlwaysOpaque);
|
| + EXPECT(graphics2d == kInvalidResource);
|
| + // NULL size -> Internal error in rpc method.
|
| + graphics2d = ppb->Create(pp_instance(), NULL, kAlwaysOpaque);
|
| + EXPECT(graphics2d == kInvalidResource);
|
| + graphics2d = ppb->Create(pp_instance(), NULL, kNotAlwaysOpaque);
|
| + EXPECT(graphics2d == kInvalidResource);
|
| +
|
| + // Valid instance and size -> valid resource.
|
| + graphics2d = ppb->Create(pp_instance(), &kOnePixel, kAlwaysOpaque);
|
| + EXPECT(graphics2d != kInvalidResource);
|
| + PPBCore()->ReleaseResource(graphics2d);
|
| + graphics2d = ppb->Create(pp_instance(), &kOnePixel, kNotAlwaysOpaque);
|
| + EXPECT(graphics2d != kInvalidResource);
|
| + PPBCore()->ReleaseResource(graphics2d);
|
| + graphics2d = ppb->Create(pp_instance(), &k30x30, kAlwaysOpaque);
|
| + EXPECT(graphics2d != kInvalidResource);
|
| + PPBCore()->ReleaseResource(graphics2d);
|
| + graphics2d = ppb->Create(pp_instance(), &k30x30, kNotAlwaysOpaque);
|
| + EXPECT(graphics2d != kInvalidResource);
|
| + PPBCore()->ReleaseResource(graphics2d);
|
| + graphics2d = ppb->Create(pp_instance(), &k2500x2500, kAlwaysOpaque);
|
| + EXPECT(graphics2d != kInvalidResource);
|
| + PPBCore()->ReleaseResource(graphics2d);
|
| + graphics2d = ppb->Create(pp_instance(), &k2500x2500, kNotAlwaysOpaque);
|
| + EXPECT(graphics2d != kInvalidResource);
|
| + PPBCore()->ReleaseResource(graphics2d);
|
| +
|
| + TEST_PASSED;
|
| +}
|
| +
|
| +// Tests PPB_Graphics2D::IsGraphics2D().
|
| +void TestIsGraphics2D() {
|
| + // Invalid / non-existent / non-Graphics2D resource -> false.
|
| + EXPECT(PP_FALSE == PPBGraphics2D()->IsGraphics2D(kInvalidResource));
|
| + EXPECT(PP_FALSE == PPBGraphics2D()->IsGraphics2D(kNotAResource));
|
| + PP_Resource url_loader = PPBURLLoader()->Create(pp_instance());
|
| + CHECK(url_loader != kInvalidResource);
|
| + EXPECT(PP_FALSE == PPBGraphics2D()->IsGraphics2D(url_loader));
|
| + PPBCore()->ReleaseResource(url_loader);
|
| +
|
| + // Current Graphics2D resource -> true.
|
| + PP_Resource graphics2d = PPBGraphics2D()->Create(
|
| + pp_instance(), &k30x30, kAlwaysOpaque);
|
| + EXPECT(PP_TRUE == PPBGraphics2D()->IsGraphics2D(graphics2d));
|
| +
|
| + // Released Graphis2D resource -> false.
|
| + PPBCore()->ReleaseResource(graphics2d);
|
| + EXPECT(PP_FALSE == PPBGraphics2D()->IsGraphics2D(graphics2d));
|
| +
|
| + TEST_PASSED;
|
| +}
|
| +
|
| +// Tests PPB_Graphics2D::Describe().
|
| +void TestDescribe() {
|
| + PP_Resource graphics2d = kInvalidResource;
|
| + const PPB_Graphics2D* ppb = PPBGraphics2D();
|
| + struct PP_Size size = k90x90;
|
| + PP_Bool is_always_opaque = PP_TRUE;
|
| +
|
| + // Valid resource -> output = configuration, true.
|
| + graphics2d = ppb->Create(pp_instance(), &k30x30, kNotAlwaysOpaque);
|
| + EXPECT(PP_TRUE == ppb->Describe(graphics2d, &size, &is_always_opaque));
|
| + EXPECT(is_always_opaque == PP_FALSE && IsEqualSize(size, k30x30));
|
| + PPBCore()->ReleaseResource(graphics2d);
|
| +
|
| + graphics2d = ppb->Create(pp_instance(), &k30x30, kAlwaysOpaque);
|
| + EXPECT(PP_TRUE == ppb->Describe(graphics2d, &size, &is_always_opaque));
|
| + EXPECT(is_always_opaque == PP_TRUE && IsEqualSize(size, k30x30));
|
| + PPBCore()->ReleaseResource(graphics2d);
|
| +
|
| + // NULL outputs -> output = unchanged, false.
|
| + EXPECT(PP_FALSE == ppb->Describe(graphics2d, NULL, &is_always_opaque));
|
| + EXPECT(PP_FALSE == ppb->Describe(graphics2d, &size, NULL));
|
| + EXPECT(is_always_opaque == PP_TRUE && IsEqualSize(size, k30x30));
|
| +
|
| + // Invalid / non-existent resource -> output = 0, false.
|
| + EXPECT(PP_FALSE == ppb->Describe(kInvalidResource, &size, &is_always_opaque));
|
| + EXPECT(is_always_opaque == PP_FALSE && IsEqualSize(size, kZeroPixels));
|
| +
|
| + is_always_opaque = PP_TRUE;
|
| + size = k90x90;
|
| + EXPECT(PP_FALSE == ppb->Describe(kNotAResource, &size, &is_always_opaque));
|
| + EXPECT(is_always_opaque == PP_FALSE && IsEqualSize(size, kZeroPixels));
|
| +
|
| + TEST_PASSED;
|
| +}
|
| +
|
| +// Tests PPB_Graphics2D::PaintImageData() with specified image rect.
|
| +// Draws a blue square in the top right corner.
|
| +// Requires a visual inspection.
|
| +void TestPaintImageData() {
|
| + const PPB_Graphics2D* ppb = PPBGraphics2D();
|
| + PP_Resource graphics2d = CreateGraphics2D_90x90();
|
| + PP_Resource image_data = CreateImageData(k60x60, kSheerBlue);
|
| + PP_Resource image_data_noop = CreateImageData(k60x60, kOpaqueBlack);
|
| + PP_Rect src_rect = { PP_MakePoint(30, 30), k30x30 };
|
| + PP_Point top_left = PP_MakePoint(30, -30); // target origin = (60, 0);
|
| + PP_Point clip_up = PP_MakePoint(0, -31); // target origin = (30, -1)
|
| + PP_Point clip_left = PP_MakePoint(-31, 0); // target origin = (-1, 30)
|
| + PP_Point clip_right = PP_MakePoint(31, 0); // target origin = (61, 30)
|
| + PP_Point clip_down = PP_MakePoint(0, 31); // target origin = (30, 61)
|
| +
|
| + // Valid args -> copies to backing store and paints to screen after Flush().
|
| + ppb->PaintImageData(graphics2d, image_data, &top_left, &src_rect);
|
| +
|
| + // Invalid args -> no effect, no crash.
|
| + ppb->PaintImageData(kInvalidResource, image_data_noop, &top_left, &src_rect);
|
| + ppb->PaintImageData(kNotAResource, image_data_noop, &top_left, &src_rect);
|
| + ppb->PaintImageData(graphics2d, kInvalidResource, &top_left, &src_rect);
|
| + ppb->PaintImageData(graphics2d, kNotAResource, &top_left, &src_rect);
|
| + ppb->PaintImageData(graphics2d, image_data_noop, &clip_up, &src_rect);
|
| + ppb->PaintImageData(graphics2d, image_data_noop, &clip_left, &src_rect);
|
| + ppb->PaintImageData(graphics2d, image_data_noop, &clip_right, &src_rect);
|
| + ppb->PaintImageData(graphics2d, image_data_noop, &clip_down, &src_rect);
|
| + ppb->PaintImageData(graphics2d, image_data_noop, &kOrigin, &kBadRect);
|
| + // NULL top_left - > Internal error in rpc method.
|
| + ppb->PaintImageData(graphics2d, image_data_noop, NULL, &src_rect);
|
| + ppb->PaintImageData(kInvalidResource, kNotAResource, NULL, &src_rect);
|
| +
|
| + // Paints backing store image to screen only after Flush().
|
| + PP_Point top_right = PP_MakePoint(60, 0);
|
| + EXPECT(!IsSquareOnScreen(graphics2d, top_right, k30x30, kSheerBlue));
|
| + PP_CompletionCallback cc = MakeTestableFlushCallback(
|
| + "PaintImageDataFlushCallback", graphics2d, image_data, 1);
|
| + EXPECT(PP_OK_COMPLETIONPENDING == ppb->Flush(graphics2d, cc));
|
| + EXPECT(IsSquareOnScreen(graphics2d, top_right, k30x30, kSheerBlue));
|
| +
|
| + // This should have no effect on Flush().
|
| + ppb->PaintImageData(graphics2d, image_data_noop, &top_left, &src_rect);
|
| + PPBCore()->ReleaseResource(image_data_noop);
|
| +
|
| + TEST_PASSED;
|
| +}
|
| +
|
| +// Tests PPB_Graphics2D::PaintImageData() with default rect for entire image.
|
| +// Draws a yellow square in the bottom left corner.
|
| +// Requires a visual inspection.
|
| +void TestPaintImageDataEntire() {
|
| + const PPB_Graphics2D* ppb = PPBGraphics2D();
|
| + PP_Resource graphics2d = CreateGraphics2D_90x90();
|
| + PP_Resource image_data = CreateImageData(k30x30, kOpaqueYellow);
|
| + PP_Resource image_data_noop = CreateImageData(k30x30, kOpaqueBlack);
|
| + PP_Point bottom_left = PP_MakePoint(0, 60);
|
| + PP_Point clip_up = PP_MakePoint(0, -1);
|
| + PP_Point clip_left = PP_MakePoint(-1, 0);
|
| + PP_Point clip_right = PP_MakePoint(61, 0);
|
| + PP_Point clip_down = PP_MakePoint(0, 61);
|
| +
|
| + // Valid args -> copies to backing store.
|
| + ppb->PaintImageData(graphics2d, image_data, &bottom_left, kEntireImage);
|
| +
|
| + // Invalid args -> no effect, no crash.
|
| + ppb->PaintImageData(
|
| + kInvalidResource, image_data_noop, &bottom_left, kEntireImage);
|
| + ppb->PaintImageData(
|
| + kNotAResource, image_data_noop, &bottom_left, kEntireImage);
|
| + ppb->PaintImageData(graphics2d, kInvalidResource, &bottom_left, kEntireImage);
|
| + ppb->PaintImageData(graphics2d, kNotAResource, &bottom_left, kEntireImage);
|
| + ppb->PaintImageData(graphics2d, image_data_noop, &clip_up, kEntireImage);
|
| + ppb->PaintImageData(graphics2d, image_data_noop, &clip_left, kEntireImage);
|
| + ppb->PaintImageData(graphics2d, image_data_noop, &clip_right, kEntireImage);
|
| + ppb->PaintImageData(graphics2d, image_data_noop, &clip_down, kEntireImage);
|
| + // NULL top_left - > Internal error in rpc method.
|
| + ppb->PaintImageData(graphics2d, image_data_noop, NULL, kEntireImage);
|
| + ppb->PaintImageData(kInvalidResource, kNotAResource, NULL, kEntireImage);
|
| +
|
| + // Paints backing store image to the screen only after Flush().
|
| + EXPECT(!IsSquareOnScreen(graphics2d, bottom_left, k30x30, kOpaqueYellow));
|
| + PP_CompletionCallback cc = MakeTestableFlushCallback(
|
| + "PaintImageDataEntireFlushCallback", graphics2d, image_data, 1);
|
| + EXPECT(PP_OK_COMPLETIONPENDING == ppb->Flush(graphics2d, cc));
|
| + EXPECT(IsSquareOnScreen(graphics2d, bottom_left, k30x30, kOpaqueYellow));
|
| +
|
| + // This should have no effect on Flush().
|
| + ppb->PaintImageData(graphics2d, image_data_noop, &bottom_left, kEntireImage);
|
| + PPBCore()->ReleaseResource(image_data_noop);
|
| +
|
| + TEST_PASSED;
|
| +}
|
| +
|
| +// Tests PPB_Graphics2D::Scroll() with specified image rect.
|
| +// Draws a white square at the top left, then in the middle.
|
| +// Requires a visual inspection.
|
| +void TestScroll() {
|
| + const PPB_Graphics2D* ppb = PPBGraphics2D();
|
| + PP_Resource graphics2d = CreateGraphics2D_90x90();
|
| + PP_Resource image_data = CreateImageData(k30x30, kOpaqueWhite);
|
| + PP_Rect src_rect = { kOrigin, k30x30 };
|
| + PP_Rect clip_rect = { kOrigin, k60x60 };
|
| + PP_Point middle = PP_MakePoint(30, 30);
|
| + ppb->PaintImageData(graphics2d, image_data, &kOrigin, &src_rect);
|
| +
|
| + // Valid args -> scrolls backing store and paints to screen after Flush().
|
| + ppb->Scroll(graphics2d, &clip_rect, &middle);
|
| +
|
| + // Invalid args -> no effect, no crash.
|
| + ppb->Scroll(kInvalidResource, &clip_rect, &middle);
|
| + ppb->Scroll(kNotAResource, &clip_rect, &middle);
|
| + ppb->Scroll(graphics2d, &clip_rect, NULL); // Internal error in rpc method.
|
| +
|
| + // Paints backing store image to the sreen only after Flush().
|
| + EXPECT(!IsSquareOnScreen(graphics2d, middle, k30x30, kOpaqueWhite));
|
| + PP_CompletionCallback cc = MakeTestableFlushCallback(
|
| + "ScrollFlushCallback", graphics2d, image_data, 1);
|
| + EXPECT(PP_OK_COMPLETIONPENDING == ppb->Flush(graphics2d, cc));
|
| + EXPECT(IsSquareOnScreen(graphics2d, middle, k30x30, kOpaqueWhite));
|
| +
|
| + TEST_PASSED;
|
| +}
|
| +
|
| +// Tests PPB_Graphics2D::Scroll() with default rect for entire image..
|
| +// Draws a green square in the top left, then bottom right.
|
| +// Requires a visual inspection.
|
| +void TestScrollEntire() {
|
| + const PPB_Graphics2D* ppb = PPBGraphics2D();
|
| + PP_Resource graphics2d = CreateGraphics2D_90x90();
|
| + PP_Resource image_data = CreateImageData(k30x30, kOpaqueGreen);
|
| + PP_Point bottom_right = PP_MakePoint(60, 60);
|
| + ppb->PaintImageData(graphics2d, image_data, &kOrigin, kEntireImage);
|
| +
|
| + // Valid args -> scrolls backing store and paints to screen after Flush().
|
| + ppb->Scroll(graphics2d, kEntireImage, &bottom_right);
|
| +
|
| + // Invalid args -> no crash.
|
| + ppb->Scroll(kInvalidResource, kEntireImage, &bottom_right);
|
| + ppb->Scroll(kNotAResource, kEntireImage, &bottom_right);
|
| + ppb->Scroll(graphics2d, kEntireImage, NULL); // Internal error in rpc method.
|
| +
|
| + // Paints backing store image to the screen only after Flush().
|
| + EXPECT(!IsSquareOnScreen(graphics2d, bottom_right, k30x30, kOpaqueGreen));
|
| + ppb->Scroll(graphics2d, kEntireImage, &bottom_right);
|
| + PP_CompletionCallback cc = MakeTestableFlushCallback(
|
| + "ScrollEntireFlushCallback", graphics2d, image_data, 1);
|
| + EXPECT(PP_OK_COMPLETIONPENDING == ppb->Flush(graphics2d, cc));
|
| + EXPECT(IsSquareOnScreen(graphics2d, bottom_right, k30x30, kOpaqueGreen));
|
| +
|
| + TEST_PASSED;
|
| +}
|
| +
|
| +// Tests PPB_Graphics2D::ReplaceContents().
|
| +// Colors the entire graphics area gray.
|
| +// Requires a visual inspection.
|
| +void TestReplaceContents() {
|
| + PP_Resource graphics2d = CreateGraphics2D_90x90();
|
| + PP_Resource image_data = CreateImageData(k90x90, kSheerGray);
|
| + PP_Resource image_data_noop = CreateImageData(k90x90, kOpaqueBlack);
|
| + PP_Resource image_data_size_mismatch = CreateImageData(k30x30, kOpaqueBlack);
|
| +
|
| + // Valid args -> replaces backing store.
|
| + PPBGraphics2D()->ReplaceContents(graphics2d, image_data);
|
| +
|
| + // Invalid args -> no effect, no crash.
|
| + PPBGraphics2D()->ReplaceContents(kInvalidResource, image_data_noop);
|
| + PPBGraphics2D()->ReplaceContents(kNotAResource, image_data_noop);
|
| + PPBGraphics2D()->ReplaceContents(graphics2d, kInvalidResource);
|
| + PPBGraphics2D()->ReplaceContents(graphics2d, kNotAResource);
|
| + PPBGraphics2D()->ReplaceContents(kInvalidResource, kNotAResource);
|
| + PPBGraphics2D()->ReplaceContents(graphics2d, image_data_size_mismatch);
|
| +
|
| + // Paints backing store image to the screen only after Flush().
|
| + EXPECT(!IsSquareOnScreen(graphics2d, kOrigin, k90x90, kSheerGray));
|
| + PP_CompletionCallback cc = MakeTestableFlushCallback(
|
| + "ReplaceContentsFlushCallback", graphics2d, image_data, 1);
|
| + EXPECT(PP_OK_COMPLETIONPENDING == PPBGraphics2D()->Flush(graphics2d, cc));
|
| + EXPECT(IsSquareOnScreen(graphics2d, kOrigin, k90x90, kSheerGray));
|
| +
|
| + // This should have no effect on Flush().
|
| + PPBGraphics2D()->ReplaceContents(graphics2d, image_data_noop);
|
| + PPBCore()->ReleaseResource(image_data_noop);
|
| + PPBCore()->ReleaseResource(image_data_size_mismatch);
|
| +
|
| + TEST_PASSED;
|
| +}
|
| +
|
| +// Tests PPB_Graphics2D::Flush().
|
| +void TestFlush() {
|
| + PP_Resource graphics2d = PPBGraphics2D()->Create(
|
| + pp_instance(), &k90x90, kAlwaysOpaque);
|
| + PP_CompletionCallback cc = MakeTestableFlushCallback(
|
| + "FlushCallback", graphics2d, kInvalidResource, 1);
|
| +
|
| + // Invalid args -> PP_ERROR_BAD..., no callback.
|
| + EXPECT(PP_ERROR_BADRESOURCE == PPBGraphics2D()->Flush(kInvalidResource, cc));
|
| + EXPECT(PP_ERROR_BADRESOURCE == PPBGraphics2D()->Flush(kNotAResource, cc));
|
| + EXPECT(PP_ERROR_BADARGUMENT ==
|
| + PPBGraphics2D()->Flush(graphics2d, PP_BlockUntilComplete()));
|
| +
|
| + // Valid args -> PP_OK_COMPLETIONPENDING, expect callback.
|
| + EXPECT(PP_OK_COMPLETIONPENDING == PPBGraphics2D()->Flush(graphics2d, cc));
|
| +
|
| + // Duplicate call -> PP_ERROR_INPROGRESS, no callback.
|
| + EXPECT(PP_ERROR_INPROGRESS == PPBGraphics2D()->Flush(graphics2d, cc));
|
| +
|
| + TEST_PASSED;
|
| +}
|
| +
|
| +// Tests continious Paint/Flush chaining.
|
| +void TestFlushAnimation() {
|
| + PP_Resource graphics2d = CreateGraphics2D_90x90();
|
| + PP_Resource image_data = CreateImageData(k30x30, kSheerRed);
|
| +
|
| + PPBGraphics2D()->PaintImageData(graphics2d, image_data, &kOrigin, NULL);
|
| + PP_CompletionCallback cc = MakeTestableFlushCallback(
|
| + "FlushAnimationCallback", graphics2d, image_data, 10);
|
| + EXPECT(PP_OK_COMPLETIONPENDING == PPBGraphics2D()->Flush(graphics2d, cc));
|
| +
|
| + TEST_PASSED;
|
| +}
|
| +
|
| +// Stress testing of a large number of resources.
|
| +void TestStress() {
|
| + // TODO(nfullagar): Increase the number of resources once the cause of the
|
| + // stress test flake is fixed.
|
| + const int kManyResources = 100;
|
| + PP_Resource graphics2d[kManyResources];
|
| + const PPB_Graphics2D* ppb = PPBGraphics2D();
|
| +
|
| + for (int i = 0; i < kManyResources; i++) {
|
| + graphics2d[i] = ppb->Create(pp_instance(), &k30x30, kAlwaysOpaque);
|
| + EXPECT(graphics2d[i] != kInvalidResource);
|
| + EXPECT(PP_TRUE == ppb->IsGraphics2D(graphics2d[i]));
|
| + }
|
| + for (int i = 0; i < kManyResources; i++) {
|
| + PPBCore()->ReleaseResource(graphics2d[i]);
|
| + EXPECT(PP_FALSE == PPBGraphics2D()->IsGraphics2D(graphics2d[i]));
|
| + }
|
| +
|
| + TEST_PASSED;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +void SetupTests() {
|
| + RegisterTest("TestCreate", TestCreate);
|
| + RegisterTest("TestIsGraphics2D", TestIsGraphics2D);
|
| + RegisterTest("TestDescribe", TestDescribe);
|
| + RegisterTest("TestPaintImageData", TestPaintImageData);
|
| + RegisterTest("TestPaintImageDataEntire", TestPaintImageDataEntire);
|
| + RegisterTest("TestScroll", TestScroll);
|
| + RegisterTest("TestScrollEntire", TestScrollEntire);
|
| + RegisterTest("TestReplaceContents", TestReplaceContents);
|
| + RegisterTest("TestFlush", TestFlush);
|
| + RegisterTest("TestFlushAnimation", TestFlushAnimation);
|
| + RegisterTest("TestStress", TestStress);
|
| +}
|
| +
|
| +void SetupPluginInterfaces() {
|
| + // none
|
| +}
|
|
|