| 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 |