test_interface.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/tests/ppapi_test_lib/test_interface.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <new>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/include/nacl_macros.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/src/shared/platform/nacl_check.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/tests/ppapi_test_lib/get_browser_interface.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "native_client/tests/ppapi_test_lib/internal_utils.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_instance.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_module.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_size.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_rect.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_var.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_core.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_graphics_2d.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_image_data.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_instance.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_messaging.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/ppb_var.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/dev/ppb_testing_dev.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PostTestMessage(nacl::string test_name, nacl::string message) {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nacl::string test_message = test_name;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_message += ":";
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_message += message;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Var post_var = PPBVar()->VarFromUtf8(test_message.c_str(),
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          test_message.size());
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PPBMessaging()->PostMessage(pp_instance(), post_var);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PPBVar()->Release(post_var);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var PP_MakeString(const char* s) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PPBVar()->VarFromUtf8(s, strlen(s));
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)nacl::string StringifyVar(const PP_Var& var) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t dummy_size;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (var.type) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     return "<UNKNOWN>" +  toString(var.type);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case  PP_VARTYPE_NULL:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "<NULL>";
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case  PP_VARTYPE_BOOL:
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     return "<BOOL>" + toString(var.value.as_bool);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case  PP_VARTYPE_INT32:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     return "<INT32>" + toString(var.value.as_int);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case  PP_VARTYPE_DOUBLE:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     return "<DOUBLE>" + toString(var.value.as_double);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case PP_VARTYPE_STRING:
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     return "<STRING>" + nacl::string(PPBVar()->VarToUtf8(var, &dummy_size));
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test registration
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestTable {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return singleton intsance.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static TestTable* Get() {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static TestTable table;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &table;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddTest(nacl::string test_name, TestFunction test_function) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_map_[test_name] = test_function;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RunTest(nacl::string test_name);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NACL_DISALLOW_COPY_AND_ASSIGN(TestTable);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestTable() {}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<nacl::string, TestFunction> TestMap;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestMap test_map_;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestTable::RunTest(nacl::string test_name) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestMap::iterator it = test_map_.find(test_name);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (it == test_map_.end()) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PostTestMessage(test_name, "NOTFOUND");
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(it->second != NULL);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestFunction test_function = it->second;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return test_function();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RegisterTest(nacl::string test_name, TestFunction test_func) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestTable::Get()->AddTest(test_name, test_func);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RunTest(nacl::string test_name) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestTable::Get()->RunTest(test_name);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Testable callback support
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CallbackInfo {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  nacl::string callback_name;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_CompletionCallback user_callback;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ReportCallbackInvocationToJS(const char* callback_name) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Var callback_var = PPBVar()->VarFromUtf8(callback_name,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              strlen(callback_name));
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Report using postmessage for async tests.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PPBMessaging()->PostMessage(pp_instance(), callback_var);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PPBVar()->Release(callback_var);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CallbackWrapper(void* user_data, int32_t result) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CallbackInfo* callback_info = reinterpret_cast<CallbackInfo*>(user_data);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_RunCompletionCallback(&callback_info->user_callback, result);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReportCallbackInvocationToJS(callback_info->callback_name.c_str());
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete callback_info;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_CompletionCallback MakeTestableCompletionCallback(
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* callback_name,  // Tested for by JS harness.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_CompletionCallback_Func func,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void* user_data) {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(callback_name != NULL && strlen(callback_name) > 0);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(func != NULL);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CallbackInfo* callback_info = new(std::nothrow) CallbackInfo;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(callback_info != NULL);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_info->callback_name = callback_name;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback_info->user_callback =
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_MakeOptionalCompletionCallback(func, user_data);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_MakeOptionalCompletionCallback(CallbackWrapper, callback_info);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_CompletionCallback MakeTestableCompletionCallback(
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* callback_name,  // Tested for by JS harness.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_CompletionCallback_Func func) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return MakeTestableCompletionCallback(callback_name, func, NULL);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PPAPI Helpers
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsSizeInRange(PP_Size size, PP_Size min_size, PP_Size max_size) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (min_size.width <= size.width && size.width <= max_size.width &&
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          min_size.height <= size.height && size.height <= max_size.height);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsSizeEqual(PP_Size size, PP_Size expected) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (size.width == expected.width && size.height == expected.height);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsRectEqual(PP_Rect position, PP_Rect expected) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (position.point.x == expected.point.x &&
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          position.point.y == expected.point.y &&
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          IsSizeEqual(position.size, expected.size));
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t FormatColor(PP_ImageDataFormat format, ColorPremul color) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (format == PP_IMAGEDATAFORMAT_BGRA_PREMUL)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (color.A << 24) | (color.R << 16) | (color.G << 8) | (color.B);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (format == PP_IMAGEDATAFORMAT_RGBA_PREMUL)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (color.A << 24) | (color.B << 16) | (color.G << 8) | (color.R);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NACL_NOTREACHED();
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Resource CreateImageData(PP_Size size, ColorPremul pixel_color, void** bmp) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_ImageDataFormat image_format = PPBImageData()->GetNativeImageDataFormat();
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t formatted_pixel_color = FormatColor(image_format, pixel_color);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Resource image_data = PPBImageData()->Create(
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pp_instance(), image_format, &size, PP_TRUE /*init_to_zero*/);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(image_data != kInvalidResource);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_ImageDataDesc image_desc;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(PPBImageData()->Describe(image_data, &image_desc) == PP_TRUE);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *bmp = NULL;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *bmp = PPBImageData()->Map(image_data);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(*bmp != NULL);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t* bmp_words = static_cast<uint32_t*>(*bmp);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_pixels = image_desc.stride / kBytesPerPixel * image_desc.size.height;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < num_pixels; i++)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bmp_words[i] = formatted_pixel_color;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return image_data;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsImageRectOnScreen(PP_Resource graphics2d,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         PP_Point origin,
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         PP_Size size,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         ColorPremul color) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Size size2d;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Bool dummy;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(PP_TRUE == PPBGraphics2D()->Describe(graphics2d, &size2d, &dummy));
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* bitmap = NULL;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Resource image = CreateImageData(size2d, kOpaqueBlack, &bitmap);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_ImageDataDesc image_desc;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(PP_TRUE == PPBImageData()->Describe(image, &image_desc));
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t stride = image_desc.stride / kBytesPerPixel;  // width + padding.
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32_t expected_color = FormatColor(image_desc.format, color);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(origin.x >= 0 && origin.y >= 0 &&
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (origin.x + size.width) <= stride &&
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (origin.y + size.height) <= image_desc.size.height);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(PP_TRUE == PPBTestingDev()->ReadImageData(graphics2d, image, &kOrigin));
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool found_error = false;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int y = origin.y; y < origin.y + size.height && !found_error; y++) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int x = origin.x; x < origin.x + size.width && !found_error; x++) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      uint32_t pixel_color = static_cast<uint32_t*>(bitmap)[stride * y + x];
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      found_error = (pixel_color != expected_color);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PPBCore()->ReleaseResource(image);
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !found_error;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
238