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
;
37 struct InstanceInfo
* next
;
40 /** Linked list of all live instances. */
41 struct InstanceInfo
* all_instances
= NULL
;
43 /** Returns a refed resource corresponding to the created graphics 2d. */
44 PP_Resource
MakeAndBindGraphics2D(PP_Instance instance
,
45 const struct PP_Size
* size
) {
48 graphics
= g_graphics_2d_interface
->Create(instance
, size
, PP_FALSE
);
52 if (!g_instance_interface
->BindGraphics(instance
, graphics
)) {
53 g_core_interface
->ReleaseResource(graphics
);
59 void FlushCompletionCallback(void* user_data
, int32_t result
) {
60 /* Don't need to do anything here. */
63 void Repaint(struct InstanceInfo
* instance
, const struct PP_Size
* size
) {
64 PP_Resource image
, graphics
;
65 struct PP_ImageDataDesc image_desc
;
69 /* Create image data to paint into. */
70 image
= g_image_data_interface
->Create(
71 instance
->pp_instance
, PP_IMAGEDATAFORMAT_BGRA_PREMUL
, size
, PP_TRUE
);
74 g_image_data_interface
->Describe(image
, &image_desc
);
76 /* Fill the image with blue. */
77 image_data
= (uint32_t*)g_image_data_interface
->Map(image
);
79 g_core_interface
->ReleaseResource(image
);
82 num_words
= image_desc
.stride
* size
->height
/ 4;
83 for (i
= 0; i
< num_words
; i
++)
84 image_data
[i
] = 0xFF0000FF;
86 /* Create the graphics 2d and paint the image to it. */
87 graphics
= MakeAndBindGraphics2D(instance
->pp_instance
, size
);
89 g_core_interface
->ReleaseResource(image
);
93 g_graphics_2d_interface
->ReplaceContents(graphics
, image
);
94 g_graphics_2d_interface
->Flush(graphics
,
95 PP_MakeCompletionCallback(&FlushCompletionCallback
, NULL
));
97 g_core_interface
->ReleaseResource(graphics
);
98 g_core_interface
->ReleaseResource(image
);
101 /** Returns the info for the given instance, or NULL if it's not found. */
102 struct InstanceInfo
* FindInstance(PP_Instance instance
) {
103 struct InstanceInfo
* cur
= all_instances
;
105 if (cur
->pp_instance
== instance
)
112 PP_Bool
Instance_DidCreate(PP_Instance instance
,
115 const char* argv
[]) {
116 struct InstanceInfo
* info
=
117 (struct InstanceInfo
*)malloc(sizeof(struct InstanceInfo
));
118 info
->pp_instance
= instance
;
119 info
->last_size
.width
= 0;
120 info
->last_size
.height
= 0;
122 /* Insert into linked list of live instances. */
123 info
->next
= all_instances
;
124 all_instances
= info
;
128 void Instance_DidDestroy(PP_Instance instance
) {
129 /* Find the matching item in the linked list, delete it, and patch the
132 struct InstanceInfo
** prev_ptr
= &all_instances
;
133 struct InstanceInfo
* cur
= all_instances
;
135 if (instance
== cur
->pp_instance
) {
136 *prev_ptr
= cur
->next
;
140 prev_ptr
= &cur
->next
;
145 void Instance_DidChangeView(PP_Instance pp_instance
,
147 struct PP_Rect position
;
148 struct InstanceInfo
* info
= FindInstance(pp_instance
);
152 if (g_view_interface
->GetRect(view
, &position
) == PP_FALSE
)
155 if (info
->last_size
.width
!= position
.size
.width
||
156 info
->last_size
.height
!= position
.size
.height
) {
157 /* Got a resize, repaint the plugin. */
158 Repaint(info
, &position
.size
);
159 info
->last_size
.width
= position
.size
.width
;
160 info
->last_size
.height
= position
.size
.height
;
164 void Instance_DidChangeFocus(PP_Instance pp_instance
, PP_Bool has_focus
) {
167 PP_Bool
Instance_HandleDocumentLoad(PP_Instance pp_instance
,
168 PP_Resource pp_url_loader
) {
172 static PPP_Instance instance_interface
= {
174 &Instance_DidDestroy
,
175 &Instance_DidChangeView
,
176 &Instance_DidChangeFocus
,
177 &Instance_HandleDocumentLoad
181 /* Global entrypoints --------------------------------------------------------*/
183 PP_EXPORT
int32_t PPP_InitializeModule(PP_Module module
,
184 PPB_GetInterface get_browser_interface
) {
185 g_get_browser_interface
= get_browser_interface
;
187 g_core_interface
= (const PPB_Core
*)
188 get_browser_interface(PPB_CORE_INTERFACE
);
189 g_instance_interface
= (const PPB_Instance
*)
190 get_browser_interface(PPB_INSTANCE_INTERFACE
);
191 g_image_data_interface
= (const PPB_ImageData
*)
192 get_browser_interface(PPB_IMAGEDATA_INTERFACE
);
193 g_graphics_2d_interface
= (const PPB_Graphics2D
*)
194 get_browser_interface(PPB_GRAPHICS_2D_INTERFACE
);
195 g_view_interface
= (const PPB_View
*)
196 get_browser_interface(PPB_VIEW_INTERFACE
);
197 if (!g_core_interface
|| !g_instance_interface
|| !g_image_data_interface
||
198 !g_graphics_2d_interface
|| !g_view_interface
)
204 PP_EXPORT
void PPP_ShutdownModule() {
207 PP_EXPORT
const void* PPP_GetInterface(const char* interface_name
) {
208 if (strcmp(interface_name
, PPP_INSTANCE_INTERFACE
) == 0)
209 return &instance_interface
;