// Copyright (c) 2012 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 "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_2* 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);
}

}  // namespace

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_2));
  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;
}

// Test all the functions with an invalid handle. Most of these just check for
// a crash since the browser don't return a value.
std::string TestGraphics2D::TestInvalidResource() {
  pp::Graphics2D null_context;
  pp::ImageData image(instance_, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
                      pp::Size(16, 16), true);

  // Describe.
  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);

  // PaintImageData.
  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);

  // Scroll.
  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);

  // ReplaceContents.
  graphics_2d_interface_->ReplaceContents(image.pp_resource(),
                                          image.pp_resource());
  graphics_2d_interface_->ReplaceContents(null_context.pp_resource(),
                                          image.pp_resource());

  // Flush.
  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());

  // ReadImageData.
  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));

  // Need to use the C API since pp::Size prevents negative sizes.
  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);

  // Overflow to negative size
  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());

  // Make an image with nonzero data in it (so we can test that zeros were
  // actually read versus ReadImageData being a NOP).
  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);

  // Read out the initial data from the device & check.
  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() {
  // Tests GetScale/SetScale
  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());
  // Try setting a few invalid scale factors. Ensure that we catch these errors
  // and don't change the actual scale
  ASSERT_FALSE(dc.SetScale(-1.0f));
  ASSERT_FALSE(dc.SetScale(0.0f));
  ASSERT_EQ(scale, dc.GetScale());

  // Verify that the context has the specified number of pixels, despite the
  // non-identity scale
  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());

  // Make sure the device background is 0.
  ASSERT_TRUE(IsDCUniformColor(dc, 0));

  // Fill the backing store with white.
  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));

  // Make an image to paint with that's opaque white and enqueue a paint.
  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));

  // Validate that nothing has been actually painted.
  ASSERT_TRUE(IsDCUniformColor(dc, background_color));

  // The paint hasn't been flushed so we can still change the bitmap. Fill with
  // 50% blue. This will also verify that the backing store is replaced
  // with the contents rather than blended.
  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));

  // Reset the DC to blank white & paint our image slightly off the buffer.
  // This should succeed. We also try painting the same thing where the
  // dirty rect falls outeside of the device, which should fail.
  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));

  // Now we should have a little bit of the image peeking out the top left.
  ASSERT_TRUE(IsSquareInDC(dc, background_color, pp::Rect(0, 0, 1, 1),
                           fill_color));

  // Now repaint that top left pixel by doing a subset of the source image.
  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));

  // Make sure the device background is 0.
  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));

  // Test Case 1. Incorrect usage when scrolling image to a free space.
  // The clip area is *not* the area to shift around within the graphics device
  // by specified amount. It's the area to which the scroll is limited. So if
  // the clip area is the size of the image and the amount points to free space,
  // the scroll won't result in additional images.
  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));

  // Test Case 2.
  // The amount is intended to place the image in the free space outside
  // of the original, but the clip area extends beyond the graphics device area.
  // This scroll is invalid and will be a noop.
  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));

  // Test Case 3.
  // The amount is intended to place the image in the free space outside
  // of the original, but the clip area does not cover the image,
  // so there is nothing to 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));

  // Test Case 4.
  // Same as TC3, but the clip covers part of the image.
  // This part will be scrolled to the intended origin.
  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));

  // Test Case 5
  // Same as TC3, but the clip area covers the entire image.
  // It will be scrolled to the intended origin.
  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));

  // Note that the undefined area left by the scroll does not actually get
  // cleared, so the original image is still there. This is not guaranteed and
  // is not something for users to rely on, but we can test for this here, so
  // we know when the underlying behavior changes.
  ASSERT_TRUE(ReadImageData(dc, &readback_image, pp::Point(image_x, image_y)));
  ASSERT_TRUE(CompareImages(test_image, readback_image));

  // Test Case 6.
  // Scroll image to an overlapping space. The clip area is limited
  // to the image, so this will just modify its area.
  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());

  // Replacing with a different size image should fail.
  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);

  // Fill the background with blue but don't flush yet.
  const uint32_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));

  // Replace with a green background but don't flush yet.
  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);

  // The background should be unchanged since we didn't flush yet.
  ASSERT_TRUE(IsDCUniformColor(dc, 0));

  // Test the C++ wrapper. The size of the swapped image should be reset.
  ASSERT_TRUE(!swapped.pp_resource() && !swapped.size().width() &&
              !swapped.size().height() && !swapped.data());

  // Painting with the swapped image should fail.
  dc.PaintImageData(swapped, pp::Point(0, 0));

  // Flush and make sure the result is correct.
  ASSERT_SUBTEST_SUCCESS(FlushAndWaitForDone(&dc));

  // The background should be green from the swapped image.
  ASSERT_TRUE(IsDCUniformColor(dc, swapped_color));

  PASS();
}

std::string TestGraphics2D::TestFlush() {
  // Tests that synchronous flushes (NULL callback) fail on the main thread
  // (which is the current one).
  const int w = 15, h = 17;
  pp::Graphics2D dc(instance_, pp::Size(w, h), false);
  ASSERT_FALSE(dc.is_null());

  // Fill the background with blue but don't flush yet.
  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);

  // Test flushing with no operations still issues a callback.
  // (This may also hang if the browser never issues the callback).
  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());

  // Test that multiple flushes fail if we don't get a callback in between.
  rv = dc_nopaints.Flush(callback_1.GetCallback());
  if (rv == PP_OK_COMPLETIONPENDING) {
    // If the first flush completes asynchronously, then a second should fail.
    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() {
  // Run a nested message loop. It will exit either on ViewChanged or if the
  // timeout happens.

  // If view changed before we have chance to run message loop, return directly.
  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() {
  // Tests that callback of offscreen updates should be delayed.
  const PP_Time kFlushDelaySec = 1. / 30;  // 30 fps
  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));

  // Squeeze from top until bottom half of plugin is out of screen.
  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());

  // Allocate a red image chunk
  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);

  // Paint a invisable chunk, expecting Flush to invoke callback slowly.
  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;
  // Expect actual_time_elapsed >= kFlushDelaySec, but loose a bit to avoid
  // precision issue.
  ASSERT_GE(actual_time_elapsed, kFlushDelaySec * 0.9);

  // Remove the padding on the top since test cases here isn't independent.
  instance_->EvalScript(
      "var big = document.getElementById('big-div');"
      "big.parentNode.removeChild(big);");
  ResetViewChangedState();
  ASSERT_TRUE(WaitUntilViewChanged());

  PASS();
}

std::string TestGraphics2D::TestDev() {
  // Tests GetScale/SetScale via the Graphics2D_Dev C++ wrapper
  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());
  // Try setting a few invalid scale factors. Ensure that we catch these errors
  // and don't change the actual scale
  ASSERT_FALSE(dc.SetScale(-1.0f));
  ASSERT_FALSE(dc.SetScale(0.0f));
  ASSERT_EQ(scale, dc.GetScale());

  // Verify that the context has the specified number of pixels, despite the
  // non-identity scale
  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();
}

// This test makes sure that the out-of-process image data caching works as
// expected. Doing ReplaceContents quickly should re-use the image data from
// older ones.
std::string TestGraphics2D::TestReplaceContentsCaching() {
  // The cache is only active when running in the proxy, so skip it otherwise.
  if (!testing_interface_->IsOutOfProcess())
    PASS();

  // Here we test resource IDs as a way to determine if the resource is being
  // cached and re-used. This is non-optimal since it's entirely possible
  // (and maybe better) for the proxy to return new resource IDs for the
  // re-used objects. Howevever, our current implementation does this so it is
  // an easy thing to check for.
  //
  // You could check for the shared memory pointers getting re-used, but the
  // OS is very likely to use the same memory location for a newly-mapped image
  // if one was deleted, meaning that it could pass even if the cache is broken.
  // This would then require that we add some address-re-use-preventing code
  // which would be tricky.
  std::set<PP_Resource> resources;

  pp::Size size(16, 16);
  pp::Graphics2D dc(instance_, size, false);

  // Do two replace contentses, adding the old resource IDs to our map.
  PP_Resource imageres = ReplaceContentsAndReturnID(&dc, size);
  ASSERT_TRUE(imageres);
  resources.insert(imageres);
  imageres = ReplaceContentsAndReturnID(&dc, size);
  ASSERT_TRUE(imageres);
  resources.insert(imageres);

  // Now doing more replace contents should re-use older IDs if the cache is
  // working.
  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() {
  // Binding a null resource is not an error, it should clear all bound
  // resources. We can't easily test what resource is bound, but we can test
  // that this doesn't throw an error.
  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();
}

