1 /* Copyright (c) 2012 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.
8 #include "ppapi/c/pp_completion_callback.h"
9 #include "ppapi/c/pp_errors.h"
10 #include "ppapi/c/pp_instance.h"
11 #include "ppapi/c/pp_module.h"
12 #include "ppapi/c/pp_rect.h"
13 #include "ppapi/c/pp_var.h"
14 #include "ppapi/c/ppb.h"
15 #include "ppapi/c/ppb_core.h"
16 #include "ppapi/c/ppb_graphics_2d.h"
17 #include "ppapi/c/ppb_image_data.h"
18 #include "ppapi/c/ppb_instance.h"
19 #include "ppapi/c/ppb_view.h"
20 #include "ppapi/c/ppp.h"
21 #include "ppapi/c/ppp_instance.h"
23 PPB_GetInterface g_get_browser_interface
= NULL
;
25 const PPB_Core
* g_core_interface
;
26 const PPB_Graphics2D
* g_graphics_2d_interface
;
27 const PPB_ImageData
* g_image_data_interface
;
28 const PPB_Instance
* g_instance_interface
;
29 const PPB_View
* g_view_interface
;
31 /* PPP_Instance implementation -----------------------------------------------*/
34 PP_Instance pp_instance
;
35 struct PP_Size last_size
;
38 struct InstanceInfo
* next
;
41 /** Linked list of all live instances. */
42 struct InstanceInfo
* all_instances
= NULL
;
44 /** Returns a refed resource corresponding to the created graphics 2d. */
45 PP_Resource
MakeAndBindGraphics2D(PP_Instance instance
,
46 const struct PP_Size
* size
) {
49 graphics
= g_graphics_2d_interface
->Create(instance
, size
, PP_FALSE
);
53 if (!g_instance_interface
->BindGraphics(instance
, graphics
)) {
54 g_core_interface
->ReleaseResource(graphics
);
60 void FlushCompletionCallback(void* user_data
, int32_t result
) {
61 /* Don't need to do anything here. */
64 void Repaint(struct InstanceInfo
* instance
, const struct PP_Size
* size
) {
66 struct PP_ImageDataDesc image_desc
;
70 /* Ensure the graphics 2d is ready. */
71 if (!instance
->graphics
) {
72 instance
->graphics
= MakeAndBindGraphics2D(instance
->pp_instance
, size
);
73 if (!instance
->graphics
)
77 /* Create image data to paint into. */
78 image
= g_image_data_interface
->Create(
79 instance
->pp_instance
, PP_IMAGEDATAFORMAT_BGRA_PREMUL
, size
, PP_TRUE
);
82 g_image_data_interface
->Describe(image
, &image_desc
);
84 /* Fill the image with blue. */
85 image_data
= (uint32_t*)g_image_data_interface
->Map(image
);
87 g_core_interface
->ReleaseResource(image
);
90 num_words
= image_desc
.stride
* size
->height
/ 4;
91 for (i
= 0; i
< num_words
; i
++)
92 image_data
[i
] = 0xFF0000FF;
94 /* Paint image to graphics 2d. */
95 g_graphics_2d_interface
->ReplaceContents(instance
->graphics
, image
);
96 g_graphics_2d_interface
->Flush(instance
->graphics
,
97 PP_MakeCompletionCallback(&FlushCompletionCallback
, NULL
));
99 g_core_interface
->ReleaseResource(image
);
102 /** Returns the info for the given instance, or NULL if it's not found. */
103 struct InstanceInfo
* FindInstance(PP_Instance instance
) {
104 struct InstanceInfo
* cur
= all_instances
;
106 if (cur
->pp_instance
== instance
)
113 PP_Bool
Instance_DidCreate(PP_Instance instance
,
116 const char* argv
[]) {
117 struct InstanceInfo
* info
=
118 (struct InstanceInfo
*)malloc(sizeof(struct InstanceInfo
));
119 info
->pp_instance
= instance
;
120 info
->last_size
.width
= 0;
121 info
->last_size
.height
= 0;
124 /* Insert into linked list of live instances. */
125 info
->next
= all_instances
;
126 all_instances
= info
;
130 void Instance_DidDestroy(PP_Instance instance
) {
131 /* Find the matching item in the linked list, delete it, and patch the
134 struct InstanceInfo
** prev_ptr
= &all_instances
;
135 struct InstanceInfo
* cur
= all_instances
;
137 if (instance
== cur
->pp_instance
) {
138 *prev_ptr
= cur
->next
;
139 g_core_interface
->ReleaseResource(cur
->graphics
);
143 prev_ptr
= &cur
->next
;
148 void Instance_DidChangeView(PP_Instance pp_instance
,
150 struct PP_Rect position
;
151 struct InstanceInfo
* info
= FindInstance(pp_instance
);
155 if (g_view_interface
->GetRect(view
, &position
) == PP_FALSE
)
158 if (info
->last_size
.width
!= position
.size
.width
||
159 info
->last_size
.height
!= position
.size
.height
) {
160 /* Got a resize, repaint the plugin. */
161 Repaint(info
, &position
.size
);
162 info
->last_size
.width
= position
.size
.width
;
163 info
->last_size
.height
= position
.size
.height
;
167 void Instance_DidChangeFocus(PP_Instance pp_instance
, PP_Bool has_focus
) {
170 PP_Bool
Instance_HandleDocumentLoad(PP_Instance pp_instance
,
171 PP_Resource pp_url_loader
) {
175 static PPP_Instance instance_interface
= {
177 &Instance_DidDestroy
,
178 &Instance_DidChangeView
,
179 &Instance_DidChangeFocus
,
180 &Instance_HandleDocumentLoad
184 /* Global entrypoints --------------------------------------------------------*/
186 PP_EXPORT
int32_t PPP_InitializeModule(PP_Module module
,
187 PPB_GetInterface get_browser_interface
) {
188 g_get_browser_interface
= get_browser_interface
;
190 g_core_interface
= (const PPB_Core
*)
191 get_browser_interface(PPB_CORE_INTERFACE
);
192 g_instance_interface
= (const PPB_Instance
*)
193 get_browser_interface(PPB_INSTANCE_INTERFACE
);
194 g_image_data_interface
= (const PPB_ImageData
*)
195 get_browser_interface(PPB_IMAGEDATA_INTERFACE
);
196 g_graphics_2d_interface
= (const PPB_Graphics2D
*)
197 get_browser_interface(PPB_GRAPHICS_2D_INTERFACE
);
198 g_view_interface
= (const PPB_View
*)
199 get_browser_interface(PPB_VIEW_INTERFACE
);
200 if (!g_core_interface
|| !g_instance_interface
|| !g_image_data_interface
||
201 !g_graphics_2d_interface
|| !g_view_interface
)
207 PP_EXPORT
void PPP_ShutdownModule() {
210 PP_EXPORT
const void* PPP_GetInterface(const char* interface_name
) {
211 if (strcmp(interface_name
, PPP_INSTANCE_INTERFACE
) == 0)
212 return &instance_interface
;