OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "ppapi/proxy/ppb_surface_3d_proxy.h" | |
6 | |
7 #include "gpu/command_buffer/client/gles2_implementation.h" | |
8 #include "ppapi/c/pp_errors.h" | |
9 #include "ppapi/c/pp_resource.h" | |
10 #include "ppapi/c/dev/ppb_surface_3d_dev.h" | |
11 #include "ppapi/proxy/enter_proxy.h" | |
12 #include "ppapi/proxy/plugin_dispatcher.h" | |
13 #include "ppapi/proxy/ppapi_messages.h" | |
14 #include "ppapi/proxy/ppb_context_3d_proxy.h" | |
15 #include "ppapi/thunk/enter.h" | |
16 #include "ppapi/thunk/resource_creation_api.h" | |
17 #include "ppapi/thunk/thunk.h" | |
18 | |
19 using ppapi::thunk::EnterFunctionNoLock; | |
20 using ppapi::thunk::PPB_Surface3D_API; | |
21 using ppapi::thunk::ResourceCreationAPI; | |
22 | |
23 namespace ppapi { | |
24 namespace proxy { | |
25 | |
26 namespace { | |
27 | |
28 InterfaceProxy* CreateSurface3DProxy(Dispatcher* dispatcher) { | |
29 return new PPB_Surface3D_Proxy(dispatcher); | |
30 } | |
31 | |
32 } // namespace | |
33 | |
34 // Surface3D ------------------------------------------------------------------- | |
35 | |
36 Surface3D::Surface3D(const HostResource& host_resource) | |
37 : Resource(host_resource), | |
38 context_(NULL), | |
39 current_flush_callback_(PP_BlockUntilComplete()) { | |
40 } | |
41 | |
42 Surface3D::~Surface3D() { | |
43 if (context_) | |
44 context_->BindSurfaces(0, 0); | |
45 } | |
46 | |
47 PPB_Surface3D_API* Surface3D::AsPPB_Surface3D_API() { | |
48 return this; | |
49 } | |
50 | |
51 int32_t Surface3D::SetAttrib(int32_t attribute, int32_t value) { | |
52 // TODO(alokp): Implement me. | |
53 return 0; | |
54 } | |
55 | |
56 int32_t Surface3D::GetAttrib(int32_t attribute, int32_t* value) { | |
57 // TODO(alokp): Implement me. | |
58 return 0; | |
59 } | |
60 | |
61 int32_t Surface3D::SwapBuffers(PP_CompletionCallback callback) { | |
62 // For now, disallow blocking calls. We'll need to add support for other | |
63 // threads to this later. | |
64 if (!callback.func) | |
65 return PP_ERROR_BLOCKS_MAIN_THREAD; | |
66 | |
67 if (is_flush_pending()) | |
68 return PP_ERROR_INPROGRESS; // Can't have >1 flush pending. | |
69 | |
70 if (!context_) | |
71 return PP_ERROR_FAILED; | |
72 | |
73 current_flush_callback_ = callback; | |
74 | |
75 IPC::Message* msg = new PpapiHostMsg_PPBSurface3D_SwapBuffers( | |
76 API_ID_PPB_SURFACE_3D, host_resource()); | |
77 msg->set_unblock(true); | |
78 PluginDispatcher::GetForResource(this)->Send(msg); | |
79 | |
80 context_->gles2_impl()->SwapBuffers(); | |
81 return PP_OK_COMPLETIONPENDING; | |
82 } | |
83 | |
84 void Surface3D::SwapBuffersACK(int32_t pp_error) { | |
85 PP_RunAndClearCompletionCallback(¤t_flush_callback_, pp_error); | |
86 } | |
87 | |
88 // PPB_Surface3D_Proxy --------------------------------------------------------- | |
89 | |
90 PPB_Surface3D_Proxy::PPB_Surface3D_Proxy(Dispatcher* dispatcher) | |
91 : InterfaceProxy(dispatcher), | |
92 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | |
93 } | |
94 | |
95 PPB_Surface3D_Proxy::~PPB_Surface3D_Proxy() { | |
96 } | |
97 | |
98 // static | |
99 const InterfaceProxy::Info* PPB_Surface3D_Proxy::GetInfo() { | |
100 static const Info info = { | |
101 thunk::GetPPB_Surface3D_Dev_Thunk(), | |
102 PPB_SURFACE_3D_DEV_INTERFACE, | |
103 API_ID_PPB_SURFACE_3D, | |
104 false, | |
105 &CreateSurface3DProxy, | |
106 }; | |
107 return &info; | |
108 } | |
109 | |
110 // static | |
111 PP_Resource PPB_Surface3D_Proxy::CreateProxyResource( | |
112 PP_Instance instance, | |
113 PP_Config3D_Dev config, | |
114 const int32_t* attrib_list) { | |
115 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); | |
116 if (!dispatcher) | |
117 return PP_ERROR_BADARGUMENT; | |
118 | |
119 std::vector<int32_t> attribs; | |
120 if (attrib_list) { | |
121 const int32_t* attr = attrib_list; | |
122 while(*attr != PP_GRAPHICS3DATTRIB_NONE) { | |
123 attribs.push_back(*(attr++)); // Attribute. | |
124 attribs.push_back(*(attr++)); // Value. | |
125 } | |
126 } | |
127 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE); // Always terminate. | |
128 | |
129 HostResource result; | |
130 dispatcher->Send(new PpapiHostMsg_PPBSurface3D_Create( | |
131 API_ID_PPB_SURFACE_3D, instance, config, attribs, &result)); | |
132 | |
133 if (result.is_null()) | |
134 return 0; | |
135 return (new Surface3D(result))->GetReference(); | |
136 } | |
137 | |
138 bool PPB_Surface3D_Proxy::OnMessageReceived(const IPC::Message& msg) { | |
139 bool handled = true; | |
140 IPC_BEGIN_MESSAGE_MAP(PPB_Surface3D_Proxy, msg) | |
141 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBSurface3D_Create, | |
142 OnMsgCreate) | |
143 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBSurface3D_SwapBuffers, | |
144 OnMsgSwapBuffers) | |
145 | |
146 IPC_MESSAGE_HANDLER(PpapiMsg_PPBSurface3D_SwapBuffersACK, | |
147 OnMsgSwapBuffersACK) | |
148 IPC_MESSAGE_UNHANDLED(handled = false) | |
149 IPC_END_MESSAGE_MAP() | |
150 // FIXME(brettw) handle bad messages! | |
151 return handled; | |
152 } | |
153 | |
154 void PPB_Surface3D_Proxy::OnMsgCreate(PP_Instance instance, | |
155 PP_Config3D_Dev config, | |
156 const std::vector<int32_t>& attribs, | |
157 HostResource* result) { | |
158 if (attribs.empty() || | |
159 attribs.size() % 2 != 1 || | |
160 attribs.back() != PP_GRAPHICS3DATTRIB_NONE) | |
161 return; // Bad message. | |
162 | |
163 thunk::EnterResourceCreation enter(instance); | |
164 if (enter.succeeded()) { | |
165 result->SetHostResource( | |
166 instance, | |
167 enter.functions()->CreateSurface3D(instance, config, &attribs.front())); | |
168 } | |
169 } | |
170 | |
171 void PPB_Surface3D_Proxy::OnMsgSwapBuffers(const HostResource& surface_3d) { | |
172 EnterHostFromHostResourceForceCallback<PPB_Surface3D_API> enter( | |
173 surface_3d, callback_factory_, | |
174 &PPB_Surface3D_Proxy::SendSwapBuffersACKToPlugin, surface_3d); | |
175 if (enter.succeeded()) | |
176 enter.SetResult(enter.object()->SwapBuffers(enter.callback())); | |
177 } | |
178 | |
179 void PPB_Surface3D_Proxy::OnMsgSwapBuffersACK(const HostResource& resource, | |
180 int32_t pp_error) { | |
181 EnterPluginFromHostResource<PPB_Surface3D_API> enter(resource); | |
182 if (enter.succeeded()) | |
183 static_cast<Surface3D*>(enter.object())->SwapBuffersACK(pp_error); | |
184 } | |
185 | |
186 void PPB_Surface3D_Proxy::SendSwapBuffersACKToPlugin( | |
187 int32_t result, | |
188 const HostResource& surface_3d) { | |
189 dispatcher()->Send(new PpapiMsg_PPBSurface3D_SwapBuffersACK( | |
190 API_ID_PPB_SURFACE_3D, surface_3d, result)); | |
191 } | |
192 | |
193 } // namespace proxy | |
194 } // namespace ppapi | |
OLD | NEW |