| OLD | NEW |
| (Empty) | |
| 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. |
| 5 */ |
| 6 |
| 7 /* NaCl Earth demo */ |
| 8 /* Pepper code in C */ |
| 9 |
| 10 #include "native_client/tests/earth/earth.h" |
| 11 |
| 12 #include <assert.h> |
| 13 #include <stdbool.h> |
| 14 #include <stdio.h> |
| 15 |
| 16 /* Pepper includes */ |
| 17 #include "ppapi/c/pp_completion_callback.h" |
| 18 #include "ppapi/c/pp_errors.h" |
| 19 #include "ppapi/c/pp_instance.h" |
| 20 #include "ppapi/c/pp_module.h" |
| 21 #include "ppapi/c/pp_point.h" |
| 22 #include "ppapi/c/pp_rect.h" |
| 23 #include "ppapi/c/pp_size.h" |
| 24 #include "ppapi/c/ppb_core.h" |
| 25 #include "ppapi/c/ppb_graphics_2d.h" |
| 26 #include "ppapi/c/ppb_image_data.h" |
| 27 #include "ppapi/c/ppb_instance.h" |
| 28 #include "ppapi/c/ppp.h" |
| 29 #include "ppapi/c/ppp_instance.h" |
| 30 |
| 31 #define NUMBER_OF_IMAGES 2 |
| 32 |
| 33 PPB_GetInterface g_get_browser_interface = NULL; |
| 34 |
| 35 /* NOTE on PP_Instance: In general Pepper is designed such that a |
| 36 * single plugin process can implement multiple plugin instances. |
| 37 * This might occur, for example, if a plugin were instantiated by |
| 38 * multiple <embed ...> tags in a single page. |
| 39 * |
| 40 * This implementation assumes at most one instance per plugin, |
| 41 * consistent with limitations of the current implementation of |
| 42 * Native Client. |
| 43 */ |
| 44 struct PepperState { |
| 45 const struct PPB_Core* core_interface; |
| 46 const struct PPB_Graphics2D* graphics_2d_interface; |
| 47 const struct PPB_ImageData* image_data_interface; |
| 48 const struct PPB_Instance* instance_interface; |
| 49 PP_Resource device_context; |
| 50 int32_t which_image; |
| 51 PP_Resource image[NUMBER_OF_IMAGES]; |
| 52 uint32_t* image_data[NUMBER_OF_IMAGES]; |
| 53 PP_Instance instance; |
| 54 struct PP_Rect position; |
| 55 bool ready; |
| 56 }; |
| 57 struct PepperState g_MyState; |
| 58 bool g_MyStateIsValid = false; |
| 59 |
| 60 static void Repaint(struct PepperState *mystate); |
| 61 static void FlushCompletionCallback(void* user_data, int32_t result) { |
| 62 Repaint((struct PepperState*)user_data); |
| 63 } |
| 64 |
| 65 static void Repaint(struct PepperState *mystate) { |
| 66 struct PP_Point topleft = PP_MakePoint(0, 0); |
| 67 struct PP_Rect rect = PP_MakeRectFromXYWH(0, 0, |
| 68 mystate->position.size.width, |
| 69 mystate->position.size.height); |
| 70 int show, render; |
| 71 |
| 72 /* Wait for previous rendering (if applicable) to finish */ |
| 73 Earth_Sync(); |
| 74 |
| 75 /* Double buffer - show previously rendered image. */ |
| 76 show = mystate->which_image; |
| 77 mystate->graphics_2d_interface->PaintImageData(mystate->device_context, |
| 78 mystate->image[show], |
| 79 &topleft, &rect); |
| 80 int32_t ret; |
| 81 ret = mystate->graphics_2d_interface->Flush(mystate->device_context, |
| 82 PP_MakeCompletionCallback(&FlushCompletionCallback, mystate)); |
| 83 |
| 84 /* Start Rendering into the other image while presenting. */ |
| 85 render = (mystate->which_image + 1) % NUMBER_OF_IMAGES; |
| 86 |
| 87 Earth_Draw(mystate->image_data[render], |
| 88 mystate->position.size.width, |
| 89 mystate->position.size.height); |
| 90 |
| 91 /* In next callback, show what was rendered. */ |
| 92 mystate->which_image = render; |
| 93 } |
| 94 |
| 95 static PP_Bool Instance_DidCreate(PP_Instance instance, |
| 96 uint32_t argc, |
| 97 const char* argn[], |
| 98 const char* argv[]) { |
| 99 assert(g_MyStateIsValid == false); |
| 100 |
| 101 DebugPrintf("Creating instance %x\n", instance); |
| 102 g_MyState.instance = instance; |
| 103 g_MyState.ready = false; |
| 104 g_MyStateIsValid = true; |
| 105 |
| 106 Earth_Init(argc, argn, argv); |
| 107 return PP_TRUE; |
| 108 } |
| 109 |
| 110 static void Instance_DidDestroy(PP_Instance instance) { |
| 111 assert(g_MyState.instance == instance && g_MyStateIsValid == true); |
| 112 g_MyStateIsValid = false; |
| 113 } |
| 114 |
| 115 /* Returns a refed resource corresponding to the created device context. */ |
| 116 static PP_Resource MakeAndBindDeviceContext(PP_Instance instance, |
| 117 const struct PP_Size* size) { |
| 118 PP_Resource device_context; |
| 119 |
| 120 device_context = |
| 121 g_MyState.graphics_2d_interface->Create(instance, size, PP_FALSE); |
| 122 if (!device_context) return 0; |
| 123 |
| 124 if (!g_MyState.instance_interface->BindGraphics(instance, device_context)) { |
| 125 g_MyState.core_interface->ReleaseResource(device_context); |
| 126 return 0; |
| 127 } |
| 128 return device_context; |
| 129 } |
| 130 |
| 131 static void Instance_DidChangeView(PP_Instance pp_instance, |
| 132 const struct PP_Rect* position, |
| 133 const struct PP_Rect* clip) { |
| 134 DebugPrintf("DidChangeView(%x)\n", pp_instance); |
| 135 assert(g_MyStateIsValid == true); |
| 136 assert(g_MyState.instance == pp_instance); |
| 137 |
| 138 g_MyState.position = *position; |
| 139 if (g_MyState.ready == false) { |
| 140 g_MyState.device_context = |
| 141 MakeAndBindDeviceContext(pp_instance, &position->size); |
| 142 /* create device context */ |
| 143 if (!g_MyState.device_context) { |
| 144 DebugPrintf("device_context is null!\n"); |
| 145 return; |
| 146 } |
| 147 /* |
| 148 * Create double-buffered image data. |
| 149 * Note: This example does not use transparent pixels. All pixels are |
| 150 * written into the framebuffer with alpha set to 255 (opaque) |
| 151 * Note: Pepper uses premultiplied alpha. |
| 152 */ |
| 153 g_MyState.which_image = 0; |
| 154 for (int i = 0; i < NUMBER_OF_IMAGES; ++i) { |
| 155 g_MyState.image[i] = |
| 156 g_MyState.image_data_interface->Create(pp_instance, |
| 157 PP_IMAGEDATAFORMAT_BGRA_PREMUL, &position->size, PP_TRUE); |
| 158 if (!g_MyState.image[i]) { |
| 159 DebugPrintf("image resource is invalid!\n"); |
| 160 return; |
| 161 } |
| 162 g_MyState.image_data[i] = |
| 163 (uint32_t*)g_MyState.image_data_interface->Map(g_MyState.image[i]); |
| 164 if (!g_MyState.image_data[i]) { |
| 165 DebugPrintf("could not allocate image_data\n"); |
| 166 return; |
| 167 } |
| 168 size_t size_in_bytes = position->size.width * position->size.height * |
| 169 sizeof(uint32_t); |
| 170 memset(g_MyState.image_data[i], 0, size_in_bytes); |
| 171 } |
| 172 g_MyState.ready = true; |
| 173 Repaint(&g_MyState); |
| 174 } |
| 175 } |
| 176 |
| 177 static void Instance_DidChangeFocus(PP_Instance pp_instance, |
| 178 PP_Bool has_focus) { |
| 179 } |
| 180 |
| 181 static PP_Bool Instance_HandleDocumentLoad(PP_Instance pp_instance, |
| 182 PP_Resource pp_url_loader) { |
| 183 return PP_FALSE; |
| 184 } |
| 185 |
| 186 static struct PPP_Instance instance_interface = { |
| 187 &Instance_DidCreate, |
| 188 &Instance_DidDestroy, |
| 189 &Instance_DidChangeView, |
| 190 &Instance_DidChangeFocus, |
| 191 &Instance_HandleDocumentLoad |
| 192 }; |
| 193 |
| 194 |
| 195 /* Global entrypoints --------------------------------------------------------*/ |
| 196 |
| 197 PP_EXPORT int32_t PPP_InitializeModule(PP_Module module, |
| 198 PPB_GetInterface get_browser_interface) { |
| 199 g_get_browser_interface = get_browser_interface; |
| 200 |
| 201 g_MyState.core_interface = (const struct PPB_Core*) |
| 202 get_browser_interface(PPB_CORE_INTERFACE); |
| 203 g_MyState.instance_interface = (const struct PPB_Instance*) |
| 204 get_browser_interface(PPB_INSTANCE_INTERFACE); |
| 205 g_MyState.image_data_interface = (const struct PPB_ImageData*) |
| 206 get_browser_interface(PPB_IMAGEDATA_INTERFACE); |
| 207 g_MyState.graphics_2d_interface = (const struct PPB_Graphics2D*) |
| 208 get_browser_interface(PPB_GRAPHICS_2D_INTERFACE); |
| 209 if (!g_MyState.core_interface || |
| 210 !g_MyState.instance_interface || |
| 211 !g_MyState.image_data_interface || |
| 212 !g_MyState.graphics_2d_interface) |
| 213 return -1; |
| 214 |
| 215 return PP_OK; |
| 216 } |
| 217 |
| 218 PP_EXPORT void PPP_ShutdownModule() { |
| 219 } |
| 220 |
| 221 PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { |
| 222 if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) |
| 223 return &instance_interface; |
| 224 return NULL; |
| 225 } |
| OLD | NEW |