| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/plugins/ppapi/ppb_context_3d_impl.h" | 5 #include "webkit/plugins/ppapi/ppb_context_3d_impl.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/shared_memory.h" | 8 #include "base/shared_memory.h" |
| 9 #include "gpu/command_buffer/client/gles2_cmd_helper.h" | 9 #include "gpu/command_buffer/client/gles2_cmd_helper.h" |
| 10 #include "gpu/command_buffer/client/gles2_implementation.h" | 10 #include "gpu/command_buffer/client/gles2_implementation.h" |
| 11 #include "gpu/command_buffer/common/command_buffer.h" | 11 #include "gpu/command_buffer/common/command_buffer.h" |
| 12 #include "ppapi/c/dev/ppb_context_3d_trusted_dev.h" | 12 #include "ppapi/c/dev/ppb_context_3d_trusted_dev.h" |
| 13 #include "ppapi/thunk/enter.h" |
| 13 #include "webkit/plugins/ppapi/common.h" | 14 #include "webkit/plugins/ppapi/common.h" |
| 14 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 15 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
| 15 #include "webkit/plugins/ppapi/ppb_surface_3d_impl.h" | 16 #include "webkit/plugins/ppapi/ppb_surface_3d_impl.h" |
| 16 | 17 |
| 18 using ppapi::thunk::EnterResourceNoLock; |
| 19 using ppapi::thunk::PPB_Context3D_API; |
| 20 using ppapi::thunk::PPB_Surface3D_API; |
| 21 |
| 17 namespace webkit { | 22 namespace webkit { |
| 18 namespace ppapi { | 23 namespace ppapi { |
| 19 | 24 |
| 20 namespace { | 25 namespace { |
| 21 | 26 |
| 22 // Size of the transfer buffer. | 27 // Size of the transfer buffer. |
| 23 const int32 kCommandBufferSize = 1024 * 1024; | 28 const int32 kCommandBufferSize = 1024 * 1024; |
| 24 const int32 kTransferBufferSize = 1024 * 1024; | 29 const int32 kTransferBufferSize = 1024 * 1024; |
| 25 | 30 |
| 26 bool ShmToHandle(base::SharedMemory* shm, | 31 PP_Bool ShmToHandle(base::SharedMemory* shm, |
| 27 size_t size, | 32 size_t size, |
| 28 int* shm_handle, | 33 int* shm_handle, |
| 29 uint32_t* shm_size) { | 34 uint32_t* shm_size) { |
| 30 if (!shm || !shm_handle || !shm_size) | 35 if (!shm || !shm_handle || !shm_size) |
| 31 return false; | 36 return PP_FALSE; |
| 32 #if defined(OS_POSIX) | 37 #if defined(OS_POSIX) |
| 33 *shm_handle = shm->handle().fd; | 38 *shm_handle = shm->handle().fd; |
| 34 #elif defined(OS_WIN) | 39 #elif defined(OS_WIN) |
| 35 *shm_handle = reinterpret_cast<int>(shm->handle()); | 40 *shm_handle = reinterpret_cast<int>(shm->handle()); |
| 36 #else | 41 #else |
| 37 #error "Platform not supported." | 42 #error "Platform not supported." |
| 38 #endif | 43 #endif |
| 39 *shm_size = size; | 44 *shm_size = size; |
| 40 return true; | 45 return PP_TRUE; |
| 46 } |
| 47 |
| 48 PP_Context3DTrustedState GetErrorState() { |
| 49 PP_Context3DTrustedState error_state = { 0 }; |
| 50 error_state.error = kGenericError; |
| 51 return error_state; |
| 41 } | 52 } |
| 42 | 53 |
| 43 PP_Context3DTrustedState PPStateFromGPUState(gpu::CommandBuffer::State s) { | 54 PP_Context3DTrustedState PPStateFromGPUState(gpu::CommandBuffer::State s) { |
| 44 PP_Context3DTrustedState state = { | 55 PP_Context3DTrustedState state = { |
| 45 s.num_entries, | 56 s.num_entries, |
| 46 s.get_offset, | 57 s.get_offset, |
| 47 s.put_offset, | 58 s.put_offset, |
| 48 s.token, | 59 s.token, |
| 49 static_cast<PPB_Context3DTrustedError>(s.error), | 60 static_cast<PPB_Context3DTrustedError>(s.error), |
| 50 s.generation | 61 s.generation |
| 51 }; | 62 }; |
| 52 return state; | 63 return state; |
| 53 } | 64 } |
| 54 | 65 |
| 55 PP_Resource Create(PP_Instance instance_id, | 66 } // namespace |
| 56 PP_Config3D_Dev config, | 67 |
| 57 PP_Resource share_context, | 68 PPB_Context3D_Impl::PPB_Context3D_Impl(PluginInstance* instance) |
| 58 const int32_t* attrib_list) { | 69 : Resource(instance), |
| 70 instance_(instance), |
| 71 transfer_buffer_id_(0), |
| 72 draw_surface_(NULL), |
| 73 read_surface_(NULL), |
| 74 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
| 75 } |
| 76 |
| 77 PPB_Context3D_Impl::~PPB_Context3D_Impl() { |
| 78 Destroy(); |
| 79 } |
| 80 |
| 81 // static |
| 82 PP_Resource PPB_Context3D_Impl::Create(PP_Instance pp_instance, |
| 83 PP_Config3D_Dev config, |
| 84 PP_Resource share_context, |
| 85 const int32_t* attrib_list) { |
| 59 // TODO(alokp): Support shared context. | 86 // TODO(alokp): Support shared context. |
| 60 DCHECK_EQ(0, share_context); | 87 DCHECK_EQ(0, share_context); |
| 61 if (share_context != 0) | 88 if (share_context != 0) |
| 62 return 0; | 89 return 0; |
| 63 | 90 |
| 64 PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); | 91 PluginInstance* instance = ResourceTracker::Get()->GetInstance(pp_instance); |
| 65 if (!instance) | 92 if (!instance) |
| 66 return 0; | 93 return 0; |
| 67 | 94 |
| 68 scoped_refptr<PPB_Context3D_Impl> context( | 95 scoped_refptr<PPB_Context3D_Impl> context( |
| 69 new PPB_Context3D_Impl(instance)); | 96 new PPB_Context3D_Impl(instance)); |
| 70 if (!context->Init(config, share_context, attrib_list)) | 97 if (!context->Init(config, share_context, attrib_list)) |
| 71 return 0; | 98 return 0; |
| 72 | 99 |
| 73 return context->GetReference(); | 100 return context->GetReference(); |
| 74 } | 101 } |
| 75 | 102 |
| 76 PP_Bool IsContext3D(PP_Resource resource) { | 103 // static |
| 77 return BoolToPPBool(!!Resource::GetAs<PPB_Context3D_Impl>(resource)); | 104 PP_Resource PPB_Context3D_Impl::CreateRaw(PP_Instance pp_instance, |
| 78 } | 105 PP_Config3D_Dev config, |
| 79 | 106 PP_Resource share_context, |
| 80 int32_t GetAttrib(PP_Resource context, | 107 const int32_t* attrib_list) { |
| 81 int32_t attribute, | |
| 82 int32_t* value) { | |
| 83 // TODO(alokp): Implement me. | |
| 84 return 0; | |
| 85 } | |
| 86 | |
| 87 int32_t BindSurfaces(PP_Resource context_id, | |
| 88 PP_Resource draw, | |
| 89 PP_Resource read) { | |
| 90 scoped_refptr<PPB_Context3D_Impl> context( | |
| 91 Resource::GetAs<PPB_Context3D_Impl>(context_id)); | |
| 92 if (!context.get()) | |
| 93 return PP_ERROR_BADRESOURCE; | |
| 94 | |
| 95 scoped_refptr<PPB_Surface3D_Impl> draw_surface( | |
| 96 Resource::GetAs<PPB_Surface3D_Impl>(draw)); | |
| 97 if (!draw_surface.get()) | |
| 98 return PP_ERROR_BADRESOURCE; | |
| 99 | |
| 100 scoped_refptr<PPB_Surface3D_Impl> read_surface( | |
| 101 Resource::GetAs<PPB_Surface3D_Impl>(read)); | |
| 102 if (!read_surface.get()) | |
| 103 return PP_ERROR_BADRESOURCE; | |
| 104 | |
| 105 return context->BindSurfaces(draw_surface.get(), read_surface.get()); | |
| 106 } | |
| 107 | |
| 108 int32_t GetBoundSurfaces(PP_Resource context, | |
| 109 PP_Resource* draw, | |
| 110 PP_Resource* read) { | |
| 111 // TODO(alokp): Implement me. | |
| 112 return 0; | |
| 113 } | |
| 114 | |
| 115 const PPB_Context3D_Dev ppb_context3d = { | |
| 116 &Create, | |
| 117 &IsContext3D, | |
| 118 &GetAttrib, | |
| 119 &BindSurfaces, | |
| 120 &GetBoundSurfaces, | |
| 121 }; | |
| 122 | |
| 123 PP_Resource CreateRaw(PP_Instance instance_id, | |
| 124 PP_Config3D_Dev config, | |
| 125 PP_Resource share_context, | |
| 126 const int32_t* attrib_list) { | |
| 127 // TODO(alokp): Support shared context. | 108 // TODO(alokp): Support shared context. |
| 128 DCHECK_EQ(0, share_context); | 109 DCHECK_EQ(0, share_context); |
| 129 if (share_context != 0) | 110 if (share_context != 0) |
| 130 return 0; | 111 return 0; |
| 131 | 112 |
| 132 PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); | 113 PluginInstance* instance = ResourceTracker::Get()->GetInstance(pp_instance); |
| 133 if (!instance) | 114 if (!instance) |
| 134 return 0; | 115 return 0; |
| 135 | 116 |
| 136 scoped_refptr<PPB_Context3D_Impl> context( | 117 scoped_refptr<PPB_Context3D_Impl> context( |
| 137 new PPB_Context3D_Impl(instance)); | 118 new PPB_Context3D_Impl(instance)); |
| 138 if (!context->InitRaw(config, share_context, attrib_list)) | 119 if (!context->InitRaw(config, share_context, attrib_list)) |
| 139 return 0; | 120 return 0; |
| 140 | 121 |
| 141 return context->GetReference(); | 122 return context->GetReference(); |
| 142 } | 123 } |
| 143 | 124 |
| 144 PP_Bool Initialize(PP_Resource context_id, int32_t size) { | 125 PPB_Context3D_API* PPB_Context3D_Impl::AsPPB_Context3D_API() { |
| 145 scoped_refptr<PPB_Context3D_Impl> context( | 126 return this; |
| 146 Resource::GetAs<PPB_Context3D_Impl>(context_id)); | |
| 147 if (!context.get() || !context->command_buffer()) | |
| 148 return PP_FALSE; | |
| 149 return context->command_buffer()->Initialize(size) ? PP_TRUE : PP_FALSE; | |
| 150 } | 127 } |
| 151 | 128 |
| 152 PP_Bool GetRingBuffer(PP_Resource context_id, | 129 int32_t PPB_Context3D_Impl::GetAttrib(int32_t attribute, int32_t* value) { |
| 153 int* shm_handle, | 130 // TODO(alokp): Implement me. |
| 154 uint32_t* shm_size) { | 131 return 0; |
| 155 scoped_refptr<PPB_Context3D_Impl> context( | |
| 156 Resource::GetAs<PPB_Context3D_Impl>(context_id)); | |
| 157 if (!context.get() || !context->command_buffer()) | |
| 158 return PP_FALSE; | |
| 159 | |
| 160 gpu::Buffer buffer = context->command_buffer()->GetRingBuffer(); | |
| 161 | |
| 162 return ShmToHandle(buffer.shared_memory, buffer.size, shm_handle, shm_size) | |
| 163 ? PP_TRUE : PP_FALSE; | |
| 164 } | 132 } |
| 165 | 133 |
| 166 PP_Context3DTrustedState GetState(PP_Resource context_id) { | 134 int32_t PPB_Context3D_Impl::BindSurfaces(PP_Resource draw, PP_Resource read) { |
| 167 scoped_refptr<PPB_Context3D_Impl> context( | 135 EnterResourceNoLock<PPB_Surface3D_API> enter_draw(draw, true); |
| 168 Resource::GetAs<PPB_Context3D_Impl>(context_id)); | 136 if (enter_draw.failed()) |
| 169 if (!context.get() || !context->command_buffer()) { | 137 return PP_ERROR_BADRESOURCE; |
| 170 PP_Context3DTrustedState error_state = { 0 }; | 138 PPB_Surface3D_Impl* new_draw = |
| 171 return error_state; | 139 static_cast<PPB_Surface3D_Impl*>(enter_draw.object()); |
| 172 } | |
| 173 | 140 |
| 174 return PPStateFromGPUState(context->command_buffer()->GetState()); | 141 EnterResourceNoLock<PPB_Surface3D_API> enter_read(read, true); |
| 142 if (enter_read.failed()) |
| 143 return PP_ERROR_BADRESOURCE; |
| 144 PPB_Surface3D_Impl* new_read = |
| 145 static_cast<PPB_Surface3D_Impl*>(enter_read.object()); |
| 146 |
| 147 // TODO(alokp): Support separate draw-read surfaces. |
| 148 DCHECK_EQ(new_draw, new_read); |
| 149 if (new_draw != new_read) |
| 150 return PP_GRAPHICS3DERROR_BAD_MATCH; |
| 151 |
| 152 if (new_draw == draw_surface_) |
| 153 return PP_OK; |
| 154 |
| 155 if (new_draw->context()) |
| 156 return PP_GRAPHICS3DERROR_BAD_ACCESS; // Already bound. |
| 157 |
| 158 if (draw_surface_) |
| 159 draw_surface_->BindToContext(NULL); |
| 160 if (!new_draw->BindToContext(this)) |
| 161 return PP_ERROR_NOMEMORY; |
| 162 |
| 163 draw_surface_ = new_draw; |
| 164 read_surface_ = new_read; |
| 165 return PP_OK; |
| 175 } | 166 } |
| 176 | 167 |
| 177 PP_Bool Flush(PP_Resource context_id, int32_t put_offset) { | 168 int32_t PPB_Context3D_Impl::GetBoundSurfaces(PP_Resource* draw, |
| 178 scoped_refptr<PPB_Context3D_Impl> context( | 169 PP_Resource* read) { |
| 179 Resource::GetAs<PPB_Context3D_Impl>(context_id)); | 170 // TODO(alokp): Implement me. |
| 180 if (!context.get() || !context->command_buffer()) | 171 return 0; |
| 172 } |
| 173 |
| 174 PP_Bool PPB_Context3D_Impl::InitializeTrusted(int32_t size) { |
| 175 if (!platform_context_.get()) |
| 181 return PP_FALSE; | 176 return PP_FALSE; |
| 177 return PP_FromBool(platform_context_->GetCommandBuffer()->Initialize(size)); |
| 178 } |
| 182 | 179 |
| 183 context->command_buffer()->Flush(put_offset); | 180 PP_Bool PPB_Context3D_Impl::GetRingBuffer(int* shm_handle, |
| 181 uint32_t* shm_size) { |
| 182 if (!platform_context_.get()) |
| 183 return PP_FALSE; |
| 184 gpu::Buffer buffer = platform_context_->GetCommandBuffer()->GetRingBuffer(); |
| 185 return ShmToHandle(buffer.shared_memory, buffer.size, shm_handle, shm_size); |
| 186 } |
| 187 |
| 188 PP_Context3DTrustedState PPB_Context3D_Impl::GetState() { |
| 189 if (!platform_context_.get()) |
| 190 return GetErrorState(); |
| 191 return PPStateFromGPUState(platform_context_->GetCommandBuffer()->GetState()); |
| 192 } |
| 193 |
| 194 PP_Bool PPB_Context3D_Impl::Flush(int32_t put_offset) { |
| 195 if (!platform_context_.get()) |
| 196 return PP_FALSE; |
| 197 platform_context_->GetCommandBuffer()->Flush(put_offset); |
| 184 return PP_TRUE; | 198 return PP_TRUE; |
| 185 } | 199 } |
| 186 | 200 |
| 187 PP_Context3DTrustedState FlushSync(PP_Resource context_id, int32_t put_offset) { | 201 PP_Context3DTrustedState PPB_Context3D_Impl::FlushSync(int32_t put_offset) { |
| 188 scoped_refptr<PPB_Context3D_Impl> context( | 202 if (!platform_context_.get()) |
| 189 Resource::GetAs<PPB_Context3D_Impl>(context_id)); | 203 return GetErrorState(); |
| 190 if (!context.get() || !context->command_buffer()) { | 204 gpu::CommandBuffer::State state = |
| 191 PP_Context3DTrustedState error_state = { 0 }; | 205 platform_context_->GetCommandBuffer()->GetState(); |
| 192 return error_state; | |
| 193 } | |
| 194 | |
| 195 gpu::CommandBuffer::State state = context->command_buffer()->GetState(); | |
| 196 return PPStateFromGPUState( | 206 return PPStateFromGPUState( |
| 197 context->command_buffer()->FlushSync(put_offset, state.get_offset)); | 207 platform_context_->GetCommandBuffer()->FlushSync(put_offset, |
| 208 state.get_offset)); |
| 198 } | 209 } |
| 199 | 210 |
| 200 int32_t CreateTransferBuffer(PP_Resource context_id, uint32_t size) { | 211 int32_t PPB_Context3D_Impl::CreateTransferBuffer(uint32_t size) { |
| 201 scoped_refptr<PPB_Context3D_Impl> context( | 212 if (!platform_context_.get()) |
| 202 Resource::GetAs<PPB_Context3D_Impl>(context_id)); | |
| 203 if (!context.get() || !context->command_buffer()) | |
| 204 return 0; | 213 return 0; |
| 205 return context->command_buffer()->CreateTransferBuffer(size, -1); | 214 return platform_context_->GetCommandBuffer()->CreateTransferBuffer(size, -1); |
| 206 } | 215 } |
| 207 | 216 |
| 208 PP_Bool DestroyTransferBuffer(PP_Resource context_id, int32_t id) { | 217 PP_Bool PPB_Context3D_Impl::DestroyTransferBuffer(int32_t id) { |
| 209 scoped_refptr<PPB_Context3D_Impl> context( | 218 if (!platform_context_.get()) |
| 210 Resource::GetAs<PPB_Context3D_Impl>(context_id)); | |
| 211 if (!context.get() || !context->command_buffer()) | |
| 212 return PP_FALSE; | 219 return PP_FALSE; |
| 213 context->command_buffer()->DestroyTransferBuffer(id); | 220 platform_context_->GetCommandBuffer()->DestroyTransferBuffer(id); |
| 214 return PP_TRUE; | 221 return PP_TRUE; |
| 215 } | 222 } |
| 216 | 223 |
| 217 PP_Bool GetTransferBuffer(PP_Resource context_id, | 224 PP_Bool PPB_Context3D_Impl::GetTransferBuffer(int32_t id, |
| 218 int32_t id, | 225 int* shm_handle, |
| 219 int* shm_handle, | 226 uint32_t* shm_size) { |
| 220 uint32_t* shm_size) { | 227 if (!platform_context_.get()) |
| 221 scoped_refptr<PPB_Context3D_Impl> context( | |
| 222 Resource::GetAs<PPB_Context3D_Impl>(context_id)); | |
| 223 if (!context.get() || !context->command_buffer()) | |
| 224 return PP_FALSE; | 228 return PP_FALSE; |
| 225 gpu::Buffer buffer = context->command_buffer()->GetTransferBuffer(id); | 229 gpu::Buffer buffer = |
| 226 | 230 platform_context_->GetCommandBuffer()->GetTransferBuffer(id); |
| 227 return ShmToHandle(buffer.shared_memory, buffer.size, shm_handle, shm_size) | 231 return ShmToHandle(buffer.shared_memory, buffer.size, shm_handle, shm_size); |
| 228 ? PP_TRUE : PP_FALSE; | |
| 229 } | 232 } |
| 230 | 233 |
| 231 PP_Context3DTrustedState FlushSyncFast( | 234 PP_Context3DTrustedState PPB_Context3D_Impl::FlushSyncFast( |
| 232 PP_Resource context_id, int32_t put_offset, int32 last_known_get) { | 235 int32_t put_offset, |
| 233 scoped_refptr<PPB_Context3D_Impl> context( | 236 int32_t last_known_get) { |
| 234 Resource::GetAs<PPB_Context3D_Impl>(context_id)); | 237 if (!platform_context_.get()) |
| 235 if (!context.get() || !context->command_buffer()) { | 238 return GetErrorState(); |
| 236 PP_Context3DTrustedState error_state = { 0 }; | 239 return PPStateFromGPUState( |
| 237 return error_state; | 240 platform_context_->GetCommandBuffer()->FlushSync(put_offset, |
| 241 last_known_get)); |
| 242 } |
| 243 |
| 244 void* PPB_Context3D_Impl::MapTexSubImage2DCHROMIUM(GLenum target, |
| 245 GLint level, |
| 246 GLint xoffset, |
| 247 GLint yoffset, |
| 248 GLsizei width, |
| 249 GLsizei height, |
| 250 GLenum format, |
| 251 GLenum type, |
| 252 GLenum access) { |
| 253 if (!gles2_impl_.get()) |
| 254 return NULL; |
| 255 return gles2_impl_->MapTexSubImage2DCHROMIUM( |
| 256 target, level, xoffset, yoffset, width, height, format, type, access); |
| 257 } |
| 258 |
| 259 void PPB_Context3D_Impl::UnmapTexSubImage2DCHROMIUM(const void* mem) { |
| 260 if (gles2_impl_.get()) |
| 261 gles2_impl_->UnmapTexSubImage2DCHROMIUM(mem); |
| 262 } |
| 263 |
| 264 bool PPB_Context3D_Impl::Init(PP_Config3D_Dev config, |
| 265 PP_Resource share_context, |
| 266 const int32_t* attrib_list) { |
| 267 if (!InitRaw(config, share_context, attrib_list)) |
| 268 return false; |
| 269 |
| 270 if (!CreateImplementation()) { |
| 271 Destroy(); |
| 272 return false; |
| 238 } | 273 } |
| 239 | 274 |
| 240 return PPStateFromGPUState( | 275 return true; |
| 241 context->command_buffer()->FlushSync(put_offset, last_known_get)); | |
| 242 } | |
| 243 } // namespace | |
| 244 | |
| 245 PPB_Context3D_Impl::PPB_Context3D_Impl(PluginInstance* instance) | |
| 246 : Resource(instance), | |
| 247 instance_(instance), | |
| 248 transfer_buffer_id_(0), | |
| 249 draw_surface_(NULL), | |
| 250 read_surface_(NULL), | |
| 251 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | |
| 252 } | |
| 253 | |
| 254 PPB_Context3D_Impl::~PPB_Context3D_Impl() { | |
| 255 Destroy(); | |
| 256 } | |
| 257 | |
| 258 const PPB_Context3D_Dev* PPB_Context3D_Impl::GetInterface() { | |
| 259 return &ppb_context3d; | |
| 260 } | |
| 261 | |
| 262 const PPB_Context3DTrusted_Dev* PPB_Context3D_Impl::GetTrustedInterface() { | |
| 263 static const PPB_Context3DTrusted_Dev iface = { | |
| 264 &CreateRaw, | |
| 265 &Initialize, | |
| 266 &GetRingBuffer, | |
| 267 &GetState, | |
| 268 &Flush, | |
| 269 &FlushSync, | |
| 270 &CreateTransferBuffer, | |
| 271 &DestroyTransferBuffer, | |
| 272 &GetTransferBuffer, | |
| 273 &FlushSyncFast, | |
| 274 }; | |
| 275 return &iface; | |
| 276 } | |
| 277 | |
| 278 PPB_Context3D_Impl* PPB_Context3D_Impl::AsPPB_Context3D_Impl() { | |
| 279 return this; | |
| 280 } | 276 } |
| 281 | 277 |
| 282 bool PPB_Context3D_Impl::InitRaw(PP_Config3D_Dev config, | 278 bool PPB_Context3D_Impl::InitRaw(PP_Config3D_Dev config, |
| 283 PP_Resource share_context, | 279 PP_Resource share_context, |
| 284 const int32_t* attrib_list) { | 280 const int32_t* attrib_list) { |
| 285 // Create and initialize the objects required to issue GLES2 calls. | 281 // Create and initialize the objects required to issue GLES2 calls. |
| 286 platform_context_.reset(instance()->CreateContext3D()); | 282 platform_context_.reset(instance()->CreateContext3D()); |
| 287 if (!platform_context_.get()) { | 283 if (!platform_context_.get()) { |
| 288 Destroy(); | 284 Destroy(); |
| 289 return false; | 285 return false; |
| 290 } | 286 } |
| 291 if (!platform_context_->Init()) { | 287 if (!platform_context_->Init()) { |
| 292 Destroy(); | 288 Destroy(); |
| 293 return false; | 289 return false; |
| 294 } | 290 } |
| 295 platform_context_->SetContextLostCallback( | 291 platform_context_->SetContextLostCallback( |
| 296 callback_factory_.NewCallback(&PPB_Context3D_Impl::OnContextLost)); | 292 callback_factory_.NewCallback(&PPB_Context3D_Impl::OnContextLost)); |
| 297 return true; | 293 return true; |
| 298 } | 294 } |
| 299 | 295 |
| 300 bool PPB_Context3D_Impl::Init(PP_Config3D_Dev config, | |
| 301 PP_Resource share_context, | |
| 302 const int32_t* attrib_list) { | |
| 303 if (!InitRaw(config, share_context, attrib_list)) | |
| 304 return false; | |
| 305 | |
| 306 if (!CreateImplementation()) { | |
| 307 Destroy(); | |
| 308 return false; | |
| 309 } | |
| 310 | |
| 311 return true; | |
| 312 } | |
| 313 | |
| 314 bool PPB_Context3D_Impl::CreateImplementation() { | 296 bool PPB_Context3D_Impl::CreateImplementation() { |
| 315 gpu::CommandBuffer* command_buffer = platform_context_->GetCommandBuffer(); | 297 gpu::CommandBuffer* command_buffer = platform_context_->GetCommandBuffer(); |
| 316 DCHECK(command_buffer); | 298 DCHECK(command_buffer); |
| 317 | 299 |
| 318 if (!command_buffer->Initialize(kCommandBufferSize)) | 300 if (!command_buffer->Initialize(kCommandBufferSize)) |
| 319 return false; | 301 return false; |
| 320 | 302 |
| 321 // Create the GLES2 helper, which writes the command buffer protocol. | 303 // Create the GLES2 helper, which writes the command buffer protocol. |
| 322 helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer)); | 304 helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer)); |
| 323 if (!helper_->Initialize(kCommandBufferSize)) | 305 if (!helper_->Initialize(kCommandBufferSize)) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 340 gles2_impl_.reset(new gpu::gles2::GLES2Implementation( | 322 gles2_impl_.reset(new gpu::gles2::GLES2Implementation( |
| 341 helper_.get(), | 323 helper_.get(), |
| 342 transfer_buffer.size, | 324 transfer_buffer.size, |
| 343 transfer_buffer.ptr, | 325 transfer_buffer.ptr, |
| 344 transfer_buffer_id_, | 326 transfer_buffer_id_, |
| 345 false)); | 327 false)); |
| 346 | 328 |
| 347 return true; | 329 return true; |
| 348 } | 330 } |
| 349 | 331 |
| 350 int32_t PPB_Context3D_Impl::BindSurfaces(PPB_Surface3D_Impl* draw, | |
| 351 PPB_Surface3D_Impl* read) { | |
| 352 // TODO(alokp): Support separate draw-read surfaces. | |
| 353 DCHECK_EQ(draw, read); | |
| 354 if (draw != read) | |
| 355 return PP_GRAPHICS3DERROR_BAD_MATCH; | |
| 356 | |
| 357 if (draw == draw_surface_) | |
| 358 return PP_OK; | |
| 359 | |
| 360 if (draw && draw->context()) | |
| 361 return PP_GRAPHICS3DERROR_BAD_ACCESS; | |
| 362 | |
| 363 if (draw_surface_) | |
| 364 draw_surface_->BindToContext(NULL); | |
| 365 if (draw && !draw->BindToContext(this)) | |
| 366 return PP_ERROR_NOMEMORY; | |
| 367 | |
| 368 draw_surface_ = draw; | |
| 369 read_surface_ = read; | |
| 370 return PP_OK; | |
| 371 } | |
| 372 | |
| 373 void PPB_Context3D_Impl::Destroy() { | 332 void PPB_Context3D_Impl::Destroy() { |
| 374 if (draw_surface_) | 333 if (draw_surface_) |
| 375 draw_surface_->BindToContext(NULL); | 334 draw_surface_->BindToContext(NULL); |
| 376 | 335 |
| 377 gles2_impl_.reset(); | 336 gles2_impl_.reset(); |
| 378 | 337 |
| 379 if (command_buffer() && transfer_buffer_id_ != 0) { | 338 if (platform_context_.get() && transfer_buffer_id_ != 0) { |
| 380 command_buffer()->DestroyTransferBuffer(transfer_buffer_id_); | 339 platform_context_->GetCommandBuffer()->DestroyTransferBuffer( |
| 340 transfer_buffer_id_); |
| 381 transfer_buffer_id_ = 0; | 341 transfer_buffer_id_ = 0; |
| 382 } | 342 } |
| 383 | 343 |
| 384 helper_.reset(); | 344 helper_.reset(); |
| 385 platform_context_.reset(); | 345 platform_context_.reset(); |
| 386 } | 346 } |
| 387 | 347 |
| 388 void PPB_Context3D_Impl::OnContextLost() { | 348 void PPB_Context3D_Impl::OnContextLost() { |
| 389 if (draw_surface_) | 349 if (draw_surface_) |
| 390 draw_surface_->OnContextLost(); | 350 draw_surface_->OnContextLost(); |
| 391 if (read_surface_) | 351 if (read_surface_) |
| 392 read_surface_->OnContextLost(); | 352 read_surface_->OnContextLost(); |
| 393 } | 353 } |
| 394 | 354 |
| 395 gpu::CommandBuffer *PPB_Context3D_Impl::command_buffer() { | |
| 396 return platform_context_.get() ? platform_context_->GetCommandBuffer() : NULL; | |
| 397 } | |
| 398 | |
| 399 } // namespace ppapi | 355 } // namespace ppapi |
| 400 } // namespace webkit | 356 } // namespace webkit |
| 401 | 357 |
| OLD | NEW |