Use Persistent::Reset.
[chromium-blink-merge.git] / ppapi / native_client / tests / ppapi_test_lib / test_interface.cc
blobc574bea279038565d65951c07ea973a6e1e83a73
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "native_client/tests/ppapi_test_lib/test_interface.h"
7 #include <string.h>
8 #include <map>
9 #include <new>
11 #include "native_client/src/include/nacl_macros.h"
12 #include "native_client/src/shared/platform/nacl_check.h"
13 #include "native_client/tests/ppapi_test_lib/get_browser_interface.h"
14 #include "native_client/tests/ppapi_test_lib/internal_utils.h"
16 #include "ppapi/c/pp_instance.h"
17 #include "ppapi/c/pp_module.h"
18 #include "ppapi/c/pp_size.h"
19 #include "ppapi/c/pp_rect.h"
20 #include "ppapi/c/pp_var.h"
21 #include "ppapi/c/ppb_core.h"
22 #include "ppapi/c/ppb_graphics_2d.h"
23 #include "ppapi/c/ppb_image_data.h"
24 #include "ppapi/c/ppb_instance.h"
25 #include "ppapi/c/ppb_messaging.h"
26 #include "ppapi/c/ppb_var.h"
27 #include "ppapi/c/dev/ppb_testing_dev.h"
29 void PostTestMessage(nacl::string test_name, nacl::string message) {
30 nacl::string test_message = test_name;
31 test_message += ":";
32 test_message += message;
33 PP_Var post_var = PPBVar()->VarFromUtf8(test_message.c_str(),
34 test_message.size());
35 PPBMessaging()->PostMessage(pp_instance(), post_var);
36 PPBVar()->Release(post_var);
39 PP_Var PP_MakeString(const char* s) {
40 return PPBVar()->VarFromUtf8(s, strlen(s));
43 nacl::string StringifyVar(const PP_Var& var) {
44 uint32_t dummy_size;
45 switch (var.type) {
46 default:
47 return "<UNKNOWN>" + toString(var.type);
48 case PP_VARTYPE_NULL:
49 return "<NULL>";
50 case PP_VARTYPE_BOOL:
51 return "<BOOL>" + toString(var.value.as_bool);
52 case PP_VARTYPE_INT32:
53 return "<INT32>" + toString(var.value.as_int);
54 case PP_VARTYPE_DOUBLE:
55 return "<DOUBLE>" + toString(var.value.as_double);
56 case PP_VARTYPE_STRING:
57 return "<STRING>" + nacl::string(PPBVar()->VarToUtf8(var, &dummy_size));
61 ////////////////////////////////////////////////////////////////////////////////
62 // Test registration
63 ////////////////////////////////////////////////////////////////////////////////
65 namespace {
67 class TestTable {
68 public:
69 // Return singleton intsance.
70 static TestTable* Get() {
71 static TestTable table;
72 return &table;
75 void AddTest(nacl::string test_name, TestFunction test_function) {
76 test_map_[test_name] = test_function;
78 void RunTest(nacl::string test_name);
80 private:
81 NACL_DISALLOW_COPY_AND_ASSIGN(TestTable);
83 TestTable() {}
85 typedef std::map<nacl::string, TestFunction> TestMap;
86 TestMap test_map_;
89 void TestTable::RunTest(nacl::string test_name) {
90 TestMap::iterator it = test_map_.find(test_name);
91 if (it == test_map_.end()) {
92 PostTestMessage(test_name, "NOTFOUND");
93 return;
95 CHECK(it->second != NULL);
96 TestFunction test_function = it->second;
97 return test_function();
100 } // namespace
102 void RegisterTest(nacl::string test_name, TestFunction test_func) {
103 TestTable::Get()->AddTest(test_name, test_func);
106 void RunTest(nacl::string test_name) {
107 TestTable::Get()->RunTest(test_name);
110 ////////////////////////////////////////////////////////////////////////////////
111 // Testable callback support
112 ////////////////////////////////////////////////////////////////////////////////
114 namespace {
116 struct CallbackInfo {
117 nacl::string callback_name;
118 PP_CompletionCallback user_callback;
121 void ReportCallbackInvocationToJS(const char* callback_name) {
122 PP_Var callback_var = PPBVar()->VarFromUtf8(callback_name,
123 strlen(callback_name));
124 // Report using postmessage for async tests.
125 PPBMessaging()->PostMessage(pp_instance(), callback_var);
126 PPBVar()->Release(callback_var);
129 void CallbackWrapper(void* user_data, int32_t result) {
130 CallbackInfo* callback_info = reinterpret_cast<CallbackInfo*>(user_data);
131 PP_RunCompletionCallback(&callback_info->user_callback, result);
132 ReportCallbackInvocationToJS(callback_info->callback_name.c_str());
133 delete callback_info;
136 } // namespace
138 PP_CompletionCallback MakeTestableCompletionCallback(
139 const char* callback_name, // Tested for by JS harness.
140 PP_CompletionCallback_Func func,
141 void* user_data) {
142 CHECK(callback_name != NULL && strlen(callback_name) > 0);
143 CHECK(func != NULL);
145 CallbackInfo* callback_info = new(std::nothrow) CallbackInfo;
146 CHECK(callback_info != NULL);
147 callback_info->callback_name = callback_name;
148 callback_info->user_callback =
149 PP_MakeOptionalCompletionCallback(func, user_data);
151 return PP_MakeOptionalCompletionCallback(CallbackWrapper, callback_info);
154 PP_CompletionCallback MakeTestableCompletionCallback(
155 const char* callback_name, // Tested for by JS harness.
156 PP_CompletionCallback_Func func) {
157 return MakeTestableCompletionCallback(callback_name, func, NULL);
161 ////////////////////////////////////////////////////////////////////////////////
162 // PPAPI Helpers
163 ////////////////////////////////////////////////////////////////////////////////
165 bool IsSizeInRange(PP_Size size, PP_Size min_size, PP_Size max_size) {
166 return (min_size.width <= size.width && size.width <= max_size.width &&
167 min_size.height <= size.height && size.height <= max_size.height);
170 bool IsSizeEqual(PP_Size size, PP_Size expected) {
171 return (size.width == expected.width && size.height == expected.height);
174 bool IsRectEqual(PP_Rect position, PP_Rect expected) {
175 return (position.point.x == expected.point.x &&
176 position.point.y == expected.point.y &&
177 IsSizeEqual(position.size, expected.size));
180 uint32_t FormatColor(PP_ImageDataFormat format, ColorPremul color) {
181 if (format == PP_IMAGEDATAFORMAT_BGRA_PREMUL)
182 return (color.A << 24) | (color.R << 16) | (color.G << 8) | (color.B);
183 else if (format == PP_IMAGEDATAFORMAT_RGBA_PREMUL)
184 return (color.A << 24) | (color.B << 16) | (color.G << 8) | (color.R);
185 else
186 NACL_NOTREACHED();
189 PP_Resource CreateImageData(PP_Size size, ColorPremul pixel_color, void** bmp) {
190 PP_ImageDataFormat image_format = PPBImageData()->GetNativeImageDataFormat();
191 uint32_t formatted_pixel_color = FormatColor(image_format, pixel_color);
192 PP_Resource image_data = PPBImageData()->Create(
193 pp_instance(), image_format, &size, PP_TRUE /*init_to_zero*/);
194 CHECK(image_data != kInvalidResource);
195 PP_ImageDataDesc image_desc;
196 CHECK(PPBImageData()->Describe(image_data, &image_desc) == PP_TRUE);
197 *bmp = NULL;
198 *bmp = PPBImageData()->Map(image_data);
199 CHECK(*bmp != NULL);
200 uint32_t* bmp_words = static_cast<uint32_t*>(*bmp);
201 int num_pixels = image_desc.stride / kBytesPerPixel * image_desc.size.height;
202 for (int i = 0; i < num_pixels; i++)
203 bmp_words[i] = formatted_pixel_color;
204 return image_data;
207 bool IsImageRectOnScreen(PP_Resource graphics2d,
208 PP_Point origin,
209 PP_Size size,
210 ColorPremul color) {
211 PP_Size size2d;
212 PP_Bool dummy;
213 CHECK(PP_TRUE == PPBGraphics2D()->Describe(graphics2d, &size2d, &dummy));
215 void* bitmap = NULL;
216 PP_Resource image = CreateImageData(size2d, kOpaqueBlack, &bitmap);
218 PP_ImageDataDesc image_desc;
219 CHECK(PP_TRUE == PPBImageData()->Describe(image, &image_desc));
220 int32_t stride = image_desc.stride / kBytesPerPixel; // width + padding.
221 uint32_t expected_color = FormatColor(image_desc.format, color);
222 CHECK(origin.x >= 0 && origin.y >= 0 &&
223 (origin.x + size.width) <= stride &&
224 (origin.y + size.height) <= image_desc.size.height);
226 CHECK(PP_TRUE == PPBTestingDev()->ReadImageData(graphics2d, image, &kOrigin));
227 bool found_error = false;
228 for (int y = origin.y; y < origin.y + size.height && !found_error; y++) {
229 for (int x = origin.x; x < origin.x + size.width && !found_error; x++) {
230 uint32_t pixel_color = static_cast<uint32_t*>(bitmap)[stride * y + x];
231 found_error = (pixel_color != expected_color);
235 PPBCore()->ReleaseResource(image);
236 return !found_error;