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 |