This source file includes following definitions.
- CanFlushContext
- CanFlushContextC
- post_quit_on_view_changed_
- Init
- RunTests
- QuitMessageLoop
- ReadImageData
- IsDCUniformColor
- FlushAndWaitForDone
- FillRectInImage
- FillImageWithGradient
- CompareImages
- CompareImageRect
- IsSquareInImage
- IsSquareInDC
- ReplaceContentsAndReturnID
- TestInvalidResource
- TestInvalidSize
- TestHumongous
- TestInitToZero
- TestDescribe
- TestScale
- TestPaint
- TestScroll
- TestReplace
- TestFlush
- DidChangeView
- ResetViewChangedState
- WaitUntilViewChanged
- TestFlushOffscreenUpdate
- TestDev
- TestReplaceContentsCaching
- TestBindNull
#include "ppapi/tests/test_graphics_2d.h"
#include <stdlib.h>
#include <string.h>
#include <set>
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_graphics_2d.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/graphics_2d.h"
#include "ppapi/cpp/graphics_3d.h"
#include "ppapi/cpp/image_data.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/rect.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"
REGISTER_TEST_CASE(Graphics2D);
namespace {
bool CanFlushContext(pp::Instance* instance, pp::Graphics2D* context) {
TestCompletionCallback callback(instance->pp_instance());
callback.WaitForResult(context->Flush(callback.GetCallback()));
return (callback.result() == PP_OK);
}
bool CanFlushContextC(pp::Instance* instance, PP_Resource graphics_2d,
const PPB_Graphics2D_1_1* graphics_2d_if) {
TestCompletionCallback callback(instance->pp_instance());
callback.WaitForResult(graphics_2d_if->Flush(
graphics_2d, callback.GetCallback().pp_completion_callback()));
return (callback.result() == PP_OK);
}
}
TestGraphics2D::TestGraphics2D(TestingInstance* instance)
: TestCase(instance),
is_view_changed_(false),
post_quit_on_view_changed_(false) {
}
bool TestGraphics2D::Init() {
graphics_2d_interface_ = static_cast<const PPB_Graphics2D*>(
pp::Module::Get()->GetBrowserInterface(PPB_GRAPHICS_2D_INTERFACE_1_1));
image_data_interface_ = static_cast<const PPB_ImageData*>(
pp::Module::Get()->GetBrowserInterface(PPB_IMAGEDATA_INTERFACE_1_0));
return graphics_2d_interface_ && image_data_interface_ &&
CheckTestingInterface();
}
void TestGraphics2D::RunTests(const std::string& filter) {
RUN_TEST(InvalidResource, filter);
RUN_TEST(InvalidSize, filter);
RUN_TEST(Humongous, filter);
RUN_TEST(InitToZero, filter);
RUN_TEST(Describe, filter);
RUN_TEST(Scale, filter);
RUN_TEST_FORCEASYNC_AND_NOT(Paint, filter);
RUN_TEST_FORCEASYNC_AND_NOT(Scroll, filter);
RUN_TEST_FORCEASYNC_AND_NOT(Replace, filter);
RUN_TEST_FORCEASYNC_AND_NOT(Flush, filter);
RUN_TEST_FORCEASYNC_AND_NOT(FlushOffscreenUpdate, filter);
RUN_TEST(Dev, filter);
RUN_TEST(ReplaceContentsCaching, filter);
RUN_TEST(BindNull, filter);
}
void TestGraphics2D::QuitMessageLoop() {
testing_interface_->QuitMessageLoop(instance_->pp_instance());
}
bool TestGraphics2D::ReadImageData(const pp::Graphics2D& dc,
pp::ImageData* image,
const pp::Point& top_left) const {
return PP_ToBool(testing_interface_->ReadImageData(
dc.pp_resource(),
image->pp_resource(),
&top_left.pp_point()));
}
bool TestGraphics2D::IsDCUniformColor(const pp::Graphics2D& dc,
uint32_t color) const {
pp::ImageData readback(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
dc.size(), false);
if (readback.is_null())
return false;
if (!ReadImageData(dc, &readback, pp::Point(0, 0)))
return false;
return IsSquareInImage(readback, 0, pp::Rect(dc.size()), color);
}
std::string TestGraphics2D::FlushAndWaitForDone(pp::Graphics2D* context) {
TestCompletionCallback callback(instance_->pp_instance(), callback_type());
callback.WaitForResult(context->Flush(callback.GetCallback()));
CHECK_CALLBACK_BEHAVIOR(callback);
ASSERT_EQ(PP_OK, callback.result());
PASS();
}
void TestGraphics2D::FillRectInImage(pp::ImageData* image,
const pp::Rect& rect,
uint32_t color) const {
for (int y = rect.y(); y < rect.bottom(); y++) {
uint32_t* row = image->GetAddr32(pp::Point(rect.x(), y));
for (int pixel = 0; pixel < rect.width(); pixel++)
row[pixel] = color;
}
}
void TestGraphics2D::FillImageWithGradient(pp::ImageData* image) const {
for (int y = 0; y < image->size().height(); y++) {
uint32_t red = ((y * 256) / image->size().height()) & 0xFF;
for (int x = 0; x < image->size().width(); x++) {
uint32_t green = ((x * 256) / image->size().width()) & 0xFF;
uint32_t blue = ((red + green) / 2) & 0xFF;
uint32_t* pixel = image->GetAddr32(pp::Point(x, y));
*pixel = (blue << 24) | (green << 16) | (red << 8);
}
}
}
bool TestGraphics2D::CompareImages(const pp::ImageData& image1,
const pp::ImageData& image2) {
return CompareImageRect(
image1, pp::Rect(0, 0, image1.size().width(), image1.size().height()),
image2, pp::Rect(0, 0, image2.size().width(), image2.size().height()));
}
bool TestGraphics2D::CompareImageRect(const pp::ImageData& image1,
const pp::Rect& rc1,
const pp::ImageData& image2,
const pp::Rect& rc2) const {
if (rc1.width() != rc2.width() || rc1.height() != rc2.height())
return false;
for (int y = 0; y < rc1.height(); y++) {
for (int x = 0; x < rc1.width(); x++) {
if (*(image1.GetAddr32(pp::Point(rc1.x() + x, rc1.y() + y))) !=
*(image2.GetAddr32(pp::Point(rc2.x() + x, rc2.y() + y))))
return false;
}
}
return true;
}
bool TestGraphics2D::IsSquareInImage(const pp::ImageData& image_data,
uint32_t background_color,
const pp::Rect& square,
uint32_t square_color) const {
for (int y = 0; y < image_data.size().height(); y++) {
for (int x = 0; x < image_data.size().width(); x++) {
uint32_t pixel = *image_data.GetAddr32(pp::Point(x, y));
uint32_t desired_color;
if (square.Contains(x, y))
desired_color = square_color;
else
desired_color = background_color;
if (pixel != desired_color)
return false;
}
}
return true;
}
bool TestGraphics2D::IsSquareInDC(const pp::Graphics2D& dc,
uint32_t background_color,
const pp::Rect& square,
uint32_t square_color) const {
pp::ImageData readback(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
dc.size(), false);
if (readback.is_null())
return false;
if (!ReadImageData(dc, &readback, pp::Point(0, 0)))
return false;
return IsSquareInImage(readback, background_color, square, square_color);
}
PP_Resource TestGraphics2D::ReplaceContentsAndReturnID(
pp::Graphics2D* dc,
const pp::Size& size) {
pp::ImageData image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL, size, true);
PP_Resource id = image.pp_resource();
dc->ReplaceContents(&image);
std::string result = FlushAndWaitForDone(dc);
if (!result.empty())
return 0;
return id;
}
std::string TestGraphics2D::TestInvalidResource() {
pp::Graphics2D null_context;
pp::ImageData image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
pp::Size(16, 16), true);
PP_Size size;
PP_Bool opaque;
graphics_2d_interface_->Describe(image.pp_resource(), &size, &opaque);
graphics_2d_interface_->Describe(null_context.pp_resource(),
&size, &opaque);
PP_Point zero_zero;
zero_zero.x = 0;
zero_zero.y = 0;
graphics_2d_interface_->PaintImageData(image.pp_resource(),
image.pp_resource(),
&zero_zero, NULL);
graphics_2d_interface_->PaintImageData(null_context.pp_resource(),
image.pp_resource(),
&zero_zero, NULL);
PP_Point zero_ten;
zero_ten.x = 0;
zero_ten.y = 10;
graphics_2d_interface_->Scroll(image.pp_resource(), NULL, &zero_ten);
graphics_2d_interface_->Scroll(null_context.pp_resource(),
NULL, &zero_ten);
graphics_2d_interface_->ReplaceContents(image.pp_resource(),
image.pp_resource());
graphics_2d_interface_->ReplaceContents(null_context.pp_resource(),
image.pp_resource());
TestCompletionCallback cb(instance_->pp_instance(), PP_OPTIONAL);
cb.WaitForResult(
graphics_2d_interface_->Flush(image.pp_resource(),
cb.GetCallback().pp_completion_callback()));
ASSERT_EQ(PP_ERROR_BADRESOURCE, cb.result());
cb.WaitForResult(
graphics_2d_interface_->Flush(null_context.pp_resource(),
cb.GetCallback().pp_completion_callback()));
ASSERT_EQ(PP_ERROR_BADRESOURCE, cb.result());
ASSERT_FALSE(testing_interface_->ReadImageData(image.pp_resource(),
image.pp_resource(),
&zero_zero));
ASSERT_FALSE(testing_interface_->ReadImageData(null_context.pp_resource(),
image.pp_resource(),
&zero_zero));
PASS();
}
std::string TestGraphics2D::TestInvalidSize() {
pp::Graphics2D a(instance_, pp::Size(16, 0), false);
ASSERT_FALSE(CanFlushContext(instance_, &a));
pp::Graphics2D b(instance_, pp::Size(0, 16), false);
ASSERT_FALSE(CanFlushContext(instance_, &b));
PP_Size size;
size.width = 16;
size.height = -16;
PP_Resource graphics = graphics_2d_interface_->Create(
instance_->pp_instance(), &size, PP_FALSE);
ASSERT_FALSE(CanFlushContextC(instance_, graphics, graphics_2d_interface_));
pp::Module::Get()->core()->ReleaseResource(graphics);
size.width = -16;
size.height = 16;
graphics = graphics_2d_interface_->Create(
instance_->pp_instance(), &size, PP_FALSE);
ASSERT_FALSE(CanFlushContextC(instance_, graphics, graphics_2d_interface_));
pp::Module::Get()->core()->ReleaseResource(graphics);
size.width = std::numeric_limits<int32_t>::max();
size.height = std::numeric_limits<int32_t>::max();
graphics = graphics_2d_interface_->Create(
instance_->pp_instance(), &size, PP_FALSE);
ASSERT_FALSE(CanFlushContextC(instance_, graphics, graphics_2d_interface_));
pp::Module::Get()->core()->ReleaseResource(graphics);
PASS();
}
std::string TestGraphics2D::TestHumongous() {
pp::Graphics2D a(instance_, pp::Size(100000, 100000), false);
ASSERT_FALSE(CanFlushContext(instance_, &a));
PASS();
}
std::string TestGraphics2D::TestInitToZero() {
const int w = 15, h = 17;
pp::Graphics2D dc(instance_, pp::Size(w, h), false);
ASSERT_FALSE(dc.is_null());
pp::ImageData image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
pp::Size(w, h), true);
ASSERT_FALSE(image.is_null());
ASSERT_FALSE(image.size().IsEmpty());
memset(image.data(), 0xFF, image.stride() * image.size().height() * 4);
ASSERT_TRUE(ReadImageData(dc, &image, pp::Point(0, 0)));
ASSERT_TRUE(IsSquareInImage(image, 0, pp::Rect(0, 0, w, h), 0));
PASS();
}
std::string TestGraphics2D::TestDescribe() {
const int w = 15, h = 17;
const bool always_opaque = (::rand() % 2 == 1);
pp::Graphics2D dc(instance_, pp::Size(w, h), always_opaque);
ASSERT_FALSE(dc.is_null());
PP_Size size;
size.width = -1;
size.height = -1;
PP_Bool is_always_opaque = PP_FALSE;
ASSERT_TRUE(graphics_2d_interface_->Describe(dc.pp_resource(), &size,
&is_always_opaque));
ASSERT_EQ(w, size.width);
ASSERT_EQ(h, size.height);
ASSERT_EQ(PP_FromBool(always_opaque), is_always_opaque);
PASS();
}
std::string TestGraphics2D::TestScale() {
const int w = 20, h = 16;
const float scale = 1.0f/2.0f;
pp::Graphics2D dc(instance_, pp::Size(w, h), false);
ASSERT_FALSE(dc.is_null());
ASSERT_EQ(1.0, dc.GetScale());
ASSERT_TRUE(dc.SetScale(scale));
ASSERT_EQ(scale, dc.GetScale());
ASSERT_FALSE(dc.SetScale(-1.0f));
ASSERT_FALSE(dc.SetScale(0.0f));
ASSERT_EQ(scale, dc.GetScale());
PP_Size size;
size.width = -1;
size.height = -1;
PP_Bool is_always_opaque = PP_FALSE;
ASSERT_TRUE(graphics_2d_interface_->Describe(dc.pp_resource(), &size,
&is_always_opaque));
ASSERT_EQ(w, size.width);
ASSERT_EQ(h, size.height);
ASSERT_EQ(PP_FALSE, is_always_opaque);
PASS();
}
std::string TestGraphics2D::TestPaint() {
const int w = 15, h = 17;
pp::Graphics2D dc(instance_, pp::Size(w, h), false);
ASSERT_FALSE(dc.is_null());
ASSERT_TRUE(IsDCUniformColor(dc, 0));
const uint32_t background_color = 0xFFFFFFFF;
pp::ImageData background(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
pp::Size(w, h), false);
FillRectInImage(&background, pp::Rect(0, 0, w, h), background_color);
dc.PaintImageData(background, pp::Point(0, 0));
ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc));
const int fill_w = 2, fill_h = 3;
pp::ImageData fill(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
pp::Size(fill_w, fill_h), true);
ASSERT_FALSE(fill.is_null());
FillRectInImage(&fill, pp::Rect(fill.size()), background_color);
const int paint_x = 4, paint_y = 5;
dc.PaintImageData(fill, pp::Point(paint_x, paint_y));
ASSERT_TRUE(IsDCUniformColor(dc, background_color));
const uint32_t fill_color = 0x80000080;
FillRectInImage(&fill, pp::Rect(fill.size()), fill_color);
ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc));
ASSERT_TRUE(IsSquareInDC(dc, background_color,
pp::Rect(paint_x, paint_y, fill_w, fill_h),
fill_color));
dc.PaintImageData(background, pp::Point(0, 0));
const int second_paint_x = -1, second_paint_y = -2;
dc.PaintImageData(fill, pp::Point(second_paint_x, second_paint_y));
dc.PaintImageData(fill, pp::Point(second_paint_x, second_paint_y),
pp::Rect(-second_paint_x, -second_paint_y, 1, 1));
ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc));
ASSERT_TRUE(IsSquareInDC(dc, background_color, pp::Rect(0, 0, 1, 1),
fill_color));
pp::ImageData subset(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
pp::Size(w, h), false);
uint32_t subset_color = 0x80808080;
const int subset_x = 2, subset_y = 1;
*subset.GetAddr32(pp::Point(subset_x, subset_y)) = subset_color;
dc.PaintImageData(subset, pp::Point(-subset_x, -subset_y),
pp::Rect(subset_x, subset_y, 1, 1));
ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc));
ASSERT_TRUE(IsSquareInDC(dc, background_color, pp::Rect(0, 0, 1, 1),
subset_color));
PASS();
}
std::string TestGraphics2D::TestScroll() {
const int w = 115, h = 117;
pp::Graphics2D dc(instance_, pp::Size(w, h), false);
ASSERT_FALSE(dc.is_null());
ASSERT_TRUE(instance_->BindGraphics(dc));
ASSERT_TRUE(IsDCUniformColor(dc, 0));
const int image_width = 15, image_height = 23;
pp::ImageData test_image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
pp::Size(image_width, image_height), false);
FillImageWithGradient(&test_image);
pp::ImageData no_image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
pp::Size(image_width, image_height), false);
FillRectInImage(&no_image, pp::Rect(0, 0, image_width, image_height), 0);
pp::ImageData readback_image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
pp::Size(image_width, image_height), false);
pp::ImageData readback_scroll(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
pp::Size(image_width, image_height), false);
ASSERT_EQ(pp::Size(image_width, image_height), test_image.size());
int image_x = 51, image_y = 72;
dc.PaintImageData(test_image, pp::Point(image_x, image_y));
ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc));
int dx = -40, dy = -48;
int scroll_x = image_x + dx, scroll_y = image_y + dy;
pp::Rect clip(image_x, image_y, image_width, image_height);
dc.Scroll(clip, pp::Point(dx, dy));
ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc));
ASSERT_TRUE(
ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y)));
ASSERT_TRUE(CompareImages(no_image, readback_scroll));
scroll_x = 11, scroll_y = 24;
clip = pp::Rect(0, 0, w, h + 1);
dc.Scroll(clip, pp::Point(scroll_x - image_x, scroll_y - image_y));
ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc));
ASSERT_TRUE(
ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y)));
ASSERT_TRUE(CompareImages(no_image, readback_scroll));
scroll_x = 11, scroll_y = 24;
clip = pp::Rect(0, 0, image_x, image_y);
dc.Scroll(clip, pp::Point(scroll_x - image_x, scroll_y - image_y));
ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc));
ASSERT_TRUE(
ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y)));
ASSERT_TRUE(CompareImages(no_image, readback_scroll));
int part_w = image_width / 2, part_h = image_height / 2;
clip = pp::Rect(0, 0, image_x + part_w, image_y + part_h);
dc.Scroll(clip, pp::Point(scroll_x - image_x, scroll_y - image_y));
ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc));
ASSERT_TRUE(
ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y)));
ASSERT_FALSE(CompareImages(test_image, readback_scroll));
pp::Rect part_rect(part_w, part_h);
ASSERT_TRUE(
CompareImageRect(test_image, part_rect, readback_scroll, part_rect));
clip = pp::Rect(0, 0, image_x + image_width, image_y + image_height);
dc.Scroll(clip, pp::Point(scroll_x - image_x, scroll_y - image_y));
ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc));
ASSERT_TRUE(
ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y)));
ASSERT_TRUE(CompareImages(test_image, readback_scroll));
ASSERT_TRUE(ReadImageData(dc, &readback_image, pp::Point(image_x, image_y)));
ASSERT_TRUE(CompareImages(test_image, readback_image));
dx = 6;
dy = 9;
scroll_x = image_x + dx;
scroll_y = image_y + dy;
clip = pp::Rect(image_x, image_y, image_width, image_height);
dc.Scroll(clip, pp::Point(dx, dy));
ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc));
ASSERT_TRUE(ReadImageData(dc, &readback_image, pp::Point(image_x, image_y)));
ASSERT_FALSE(CompareImages(test_image, readback_image));
pp::Rect scroll_rect(image_width - dx, image_height - dy);
ASSERT_TRUE(
ReadImageData(dc, &readback_scroll, pp::Point(scroll_x, scroll_y)));
ASSERT_TRUE(
CompareImageRect(test_image, scroll_rect, readback_scroll, scroll_rect));
PASS();
}
std::string TestGraphics2D::TestReplace() {
const int w = 15, h = 17;
pp::Graphics2D dc(instance_, pp::Size(w, h), false);
ASSERT_FALSE(dc.is_null());
pp::ImageData weird_size(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
pp::Size(w - 1, h), true);
ASSERT_FALSE(weird_size.is_null());
dc.ReplaceContents(&weird_size);
const int32_t background_color = 0xFF0000FF;
pp::ImageData background(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
pp::Size(w, h), true);
ASSERT_FALSE(background.is_null());
FillRectInImage(&background, pp::Rect(0, 0, w, h), background_color);
dc.PaintImageData(background, pp::Point(0, 0));
const int32_t swapped_color = 0x00FF00FF;
pp::ImageData swapped(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
pp::Size(w, h), true);
ASSERT_FALSE(swapped.is_null());
FillRectInImage(&swapped, pp::Rect(0, 0, w, h), swapped_color);
dc.ReplaceContents(&swapped);
ASSERT_TRUE(IsDCUniformColor(dc, 0));
ASSERT_TRUE(!swapped.pp_resource() && !swapped.size().width() &&
!swapped.size().height() && !swapped.data());
dc.PaintImageData(swapped, pp::Point(0, 0));
ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc));
ASSERT_TRUE(IsDCUniformColor(dc, swapped_color));
PASS();
}
std::string TestGraphics2D::TestFlush() {
const int w = 15, h = 17;
pp::Graphics2D dc(instance_, pp::Size(w, h), false);
ASSERT_FALSE(dc.is_null());
pp::ImageData background(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
pp::Size(w, h), true);
ASSERT_FALSE(background.is_null());
dc.PaintImageData(background, pp::Point(0, 0));
int32_t rv = dc.Flush(pp::BlockUntilComplete());
ASSERT_EQ(PP_ERROR_BLOCKS_MAIN_THREAD, rv);
pp::Graphics2D dc_nopaints(instance_, pp::Size(w, h), false);
ASSERT_FALSE(dc.is_null());
ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc_nopaints));
TestCompletionCallback callback_1(instance_->pp_instance(), callback_type());
rv = dc_nopaints.Flush(callback_1.GetCallback());
if (rv == PP_OK_COMPLETIONPENDING) {
TestCompletionCallback callback_2(instance_->pp_instance(),
callback_type());
callback_2.WaitForResult(dc_nopaints.Flush(callback_2.GetCallback()));
CHECK_CALLBACK_BEHAVIOR(callback_2);
ASSERT_EQ(PP_ERROR_INPROGRESS, callback_2.result());
}
callback_1.WaitForResult(rv);
ASSERT_EQ(PP_OK, callback_1.result());
PASS();
}
void TestGraphics2D::DidChangeView(const pp::View& view) {
if (post_quit_on_view_changed_) {
post_quit_on_view_changed_ = false;
is_view_changed_ = true;
testing_interface_->QuitMessageLoop(instance_->pp_instance());
}
}
void TestGraphics2D::ResetViewChangedState() {
is_view_changed_ = false;
}
bool TestGraphics2D::WaitUntilViewChanged() {
if (is_view_changed_)
return true;
post_quit_on_view_changed_ = true;
testing_interface_->RunMessageLoop(instance_->pp_instance());
post_quit_on_view_changed_ = false;
return is_view_changed_;
}
std::string TestGraphics2D::TestFlushOffscreenUpdate() {
const PP_Time kFlushDelaySec = 1. / 30;
const int w = 80, h = 80;
pp::Graphics2D dc(instance_, pp::Size(w, h), true);
ASSERT_FALSE(dc.is_null());
ASSERT_TRUE(instance_->BindGraphics(dc));
ResetViewChangedState();
instance_->EvalScript(
"var big = document.createElement('div');"
"var offset = "
" window.innerHeight - plugin.offsetTop - plugin.offsetHeight / 2;"
"big.setAttribute('id', 'big-div');"
"big.setAttribute('style', 'height: ' + offset + '; width: 100%;');"
"document.body.insertBefore(big, document.body.firstChild);");
ASSERT_TRUE(WaitUntilViewChanged());
pp::ImageData chunk(instance_, PP_IMAGEDATAFORMAT_RGBA_PREMUL,
pp::Size(w/8, h/8), true);
ASSERT_FALSE(chunk.is_null());
const uint32_t kRed = 0xff0000ff;
FillRectInImage(&chunk, pp::Rect(chunk.size()), kRed);
dc.PaintImageData(chunk, pp::Point(0, h*0.75));
PP_Time begin = pp::Module::Get()->core()->GetTime();
ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc));
PP_Time actual_time_elapsed = pp::Module::Get()->core()->GetTime() - begin;
ASSERT_GE(actual_time_elapsed, kFlushDelaySec * 0.9);
instance_->EvalScript(
"var big = document.getElementById('big-div');"
"big.parentNode.removeChild(big);");
ResetViewChangedState();
ASSERT_TRUE(WaitUntilViewChanged());
PASS();
}
std::string TestGraphics2D::TestDev() {
const int w = 20, h = 16;
const float scale = 1.0f/2.0f;
pp::Graphics2D dc(instance_, pp::Size(w, h), false);
ASSERT_FALSE(dc.is_null());
ASSERT_EQ(1.0f, dc.GetScale());
ASSERT_TRUE(dc.SetScale(scale));
ASSERT_EQ(scale, dc.GetScale());
ASSERT_FALSE(dc.SetScale(-1.0f));
ASSERT_FALSE(dc.SetScale(0.0f));
ASSERT_EQ(scale, dc.GetScale());
PP_Size size;
size.width = -1;
size.height = -1;
PP_Bool is_always_opaque = PP_FALSE;
ASSERT_TRUE(graphics_2d_interface_->Describe(dc.pp_resource(), &size,
&is_always_opaque));
ASSERT_EQ(w, size.width);
ASSERT_EQ(h, size.height);
ASSERT_EQ(PP_FALSE, is_always_opaque);
PASS();
}
std::string TestGraphics2D::TestReplaceContentsCaching() {
if (!testing_interface_->IsOutOfProcess())
PASS();
std::set<PP_Resource> resources;
pp::Size size(16, 16);
pp::Graphics2D dc(instance_, size, false);
PP_Resource imageres = ReplaceContentsAndReturnID(&dc, size);
ASSERT_TRUE(imageres);
resources.insert(imageres);
imageres = ReplaceContentsAndReturnID(&dc, size);
ASSERT_TRUE(imageres);
resources.insert(imageres);
imageres = ReplaceContentsAndReturnID(&dc, size);
ASSERT_TRUE(resources.find(imageres) != resources.end());
imageres = ReplaceContentsAndReturnID(&dc, size);
ASSERT_TRUE(resources.find(imageres) != resources.end());
PASS();
}
std::string TestGraphics2D::TestBindNull() {
ASSERT_TRUE(instance_->BindGraphics(pp::Graphics2D()));
ASSERT_TRUE(instance_->BindGraphics(pp::Graphics3D()));
const int w = 115, h = 117;
pp::Graphics2D dc(instance_, pp::Size(w, h), false);
ASSERT_FALSE(dc.is_null());
ASSERT_TRUE(instance_->BindGraphics(dc));
ASSERT_TRUE(instance_->BindGraphics(pp::Graphics2D()));
ASSERT_TRUE(instance_->BindGraphics(pp::Graphics3D()));
PASS();
}