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