| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/glue/plugins/pepper_graphics_3d.h" | 5 #include "webkit/plugins/ppapi/ppb_graphics_3d_impl.h" |
| 6 | 6 |
| 7 #include "gpu/command_buffer/common/command_buffer.h" | 7 #include "gpu/command_buffer/common/command_buffer.h" |
| 8 #include "base/singleton.h" | 8 #include "base/lazy_instance.h" |
| 9 #include "base/thread_local.h" | 9 #include "base/thread_local.h" |
| 10 #include "ppapi/c/dev/ppb_graphics_3d_dev.h" | 10 #include "ppapi/c/dev/ppb_graphics_3d_dev.h" |
| 11 #include "webkit/glue/plugins/pepper_common.h" | 11 #include "webkit/plugins/ppapi/common.h" |
| 12 #include "webkit/glue/plugins/pepper_plugin_instance.h" | 12 #include "webkit/plugins/ppapi/plugin_instance.h" |
| 13 | 13 |
| 14 namespace pepper { | 14 namespace webkit { |
| 15 namespace ppapi { |
| 15 | 16 |
| 16 namespace { | 17 namespace { |
| 17 | 18 |
| 18 struct CurrentContextTag {}; | 19 static base::LazyInstance<base::ThreadLocalPointer<PPB_Graphics3D_Impl> > |
| 19 typedef Singleton<base::ThreadLocalPointer<Graphics3D>, | 20 g_current_context_key(base::LINKER_INITIALIZED); |
| 20 DefaultSingletonTraits<base::ThreadLocalPointer<Graphics3D> >, | |
| 21 CurrentContextTag> CurrentContextKey; | |
| 22 | 21 |
| 23 // Size of the transfer buffer. | 22 // Size of the transfer buffer. |
| 24 enum { kTransferBufferSize = 512 * 1024 }; | 23 enum { kTransferBufferSize = 512 * 1024 }; |
| 25 | 24 |
| 26 PP_Bool IsGraphics3D(PP_Resource resource) { | 25 PP_Bool IsGraphics3D(PP_Resource resource) { |
| 27 return BoolToPPBool(!!Resource::GetAs<Graphics3D>(resource)); | 26 return BoolToPPBool(!!Resource::GetAs<PPB_Graphics3D_Impl>(resource)); |
| 28 } | 27 } |
| 29 | 28 |
| 30 PP_Bool GetConfigs(int32_t* configs, int32_t config_size, int32_t* num_config) { | 29 PP_Bool GetConfigs(int32_t* configs, int32_t config_size, int32_t* num_config) { |
| 31 // TODO(neb): Implement me! | 30 // TODO(neb): Implement me! |
| 32 return PP_FALSE; | 31 return PP_FALSE; |
| 33 } | 32 } |
| 34 | 33 |
| 35 PP_Bool ChooseConfig(const int32_t* attrib_list, int32_t* configs, | 34 PP_Bool ChooseConfig(const int32_t* attrib_list, int32_t* configs, |
| 36 int32_t config_size, int32_t* num_config) { | 35 int32_t config_size, int32_t* num_config) { |
| 37 // TODO(neb): Implement me! | 36 // TODO(neb): Implement me! |
| (...skipping 23 matching lines...) Expand all Loading... |
| 61 PP_Resource CreateContext(PP_Instance instance_id, int32_t config, | 60 PP_Resource CreateContext(PP_Instance instance_id, int32_t config, |
| 62 int32_t share_context, | 61 int32_t share_context, |
| 63 const int32_t* attrib_list) { | 62 const int32_t* attrib_list) { |
| 64 DCHECK_EQ(0, share_context); | 63 DCHECK_EQ(0, share_context); |
| 65 | 64 |
| 66 PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); | 65 PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); |
| 67 if (!instance) { | 66 if (!instance) { |
| 68 return 0; | 67 return 0; |
| 69 } | 68 } |
| 70 | 69 |
| 71 scoped_refptr<Graphics3D> context(new Graphics3D(instance->module())); | 70 scoped_refptr<PPB_Graphics3D_Impl> context( |
| 71 new PPB_Graphics3D_Impl(instance->module())); |
| 72 if (!context->Init(instance_id, config, attrib_list)) { | 72 if (!context->Init(instance_id, config, attrib_list)) { |
| 73 return 0; | 73 return 0; |
| 74 } | 74 } |
| 75 | 75 |
| 76 return context->GetReference(); | 76 return context->GetReference(); |
| 77 } | 77 } |
| 78 | 78 |
| 79 void* GetProcAddress(const char* name) { | 79 void* GetProcAddress(const char* name) { |
| 80 // TODO(neb): Implement me! | 80 // TODO(neb): Implement me! |
| 81 return NULL; | 81 return NULL; |
| 82 } | 82 } |
| 83 | 83 |
| 84 PP_Bool MakeCurrent(PP_Resource graphics3d) { | 84 PP_Bool MakeCurrent(PP_Resource graphics3d) { |
| 85 if (!graphics3d) { | 85 if (!graphics3d) { |
| 86 Graphics3D::ResetCurrent(); | 86 PPB_Graphics3D_Impl::ResetCurrent(); |
| 87 return PP_TRUE; | 87 return PP_TRUE; |
| 88 } else { | 88 } else { |
| 89 scoped_refptr<Graphics3D> context(Resource::GetAs<Graphics3D>(graphics3d)); | 89 scoped_refptr<PPB_Graphics3D_Impl> context( |
| 90 Resource::GetAs<PPB_Graphics3D_Impl>(graphics3d)); |
| 90 return BoolToPPBool(context.get() && context->MakeCurrent()); | 91 return BoolToPPBool(context.get() && context->MakeCurrent()); |
| 91 } | 92 } |
| 92 } | 93 } |
| 93 | 94 |
| 94 PP_Resource GetCurrentContext() { | 95 PP_Resource GetCurrentContext() { |
| 95 Graphics3D* current_context = Graphics3D::GetCurrent(); | 96 PPB_Graphics3D_Impl* current_context = PPB_Graphics3D_Impl::GetCurrent(); |
| 96 return current_context ? current_context->GetReference() : 0; | 97 return current_context ? current_context->GetReference() : 0; |
| 97 } | 98 } |
| 98 | 99 |
| 99 PP_Bool SwapBuffers(PP_Resource graphics3d) { | 100 PP_Bool SwapBuffers(PP_Resource graphics3d) { |
| 100 scoped_refptr<Graphics3D> context(Resource::GetAs<Graphics3D>(graphics3d)); | 101 scoped_refptr<PPB_Graphics3D_Impl> context( |
| 102 Resource::GetAs<PPB_Graphics3D_Impl>(graphics3d)); |
| 101 return BoolToPPBool(context && context->SwapBuffers()); | 103 return BoolToPPBool(context && context->SwapBuffers()); |
| 102 } | 104 } |
| 103 | 105 |
| 104 uint32_t GetError() { | 106 uint32_t GetError() { |
| 105 // Technically, this should return the last error that occurred on the current | 107 // Technically, this should return the last error that occurred on the current |
| 106 // thread, rather than an error associated with a particular context. | 108 // thread, rather than an error associated with a particular context. |
| 107 // TODO(apatrick): Fix this. | 109 // TODO(apatrick): Fix this. |
| 108 Graphics3D* current_context = Graphics3D::GetCurrent(); | 110 PPB_Graphics3D_Impl* current_context = PPB_Graphics3D_Impl::GetCurrent(); |
| 109 if (!current_context) | 111 if (!current_context) |
| 110 return 0; | 112 return 0; |
| 111 | 113 |
| 112 return current_context->GetError(); | 114 return current_context->GetError(); |
| 113 } | 115 } |
| 114 | 116 |
| 115 const PPB_Graphics3D_Dev ppb_graphics3d = { | 117 const PPB_Graphics3D_Dev ppb_graphics3d = { |
| 116 &IsGraphics3D, | 118 &IsGraphics3D, |
| 117 &GetConfigs, | 119 &GetConfigs, |
| 118 &ChooseConfig, | 120 &ChooseConfig, |
| 119 &GetConfigAttrib, | 121 &GetConfigAttrib, |
| 120 &QueryString, | 122 &QueryString, |
| 121 &CreateContext, | 123 &CreateContext, |
| 122 &GetProcAddress, | 124 &GetProcAddress, |
| 123 &MakeCurrent, | 125 &MakeCurrent, |
| 124 &GetCurrentContext, | 126 &GetCurrentContext, |
| 125 &SwapBuffers, | 127 &SwapBuffers, |
| 126 &GetError | 128 &GetError |
| 127 }; | 129 }; |
| 128 | 130 |
| 129 } // namespace | 131 } // namespace |
| 130 | 132 |
| 131 Graphics3D::Graphics3D(PluginModule* module) | 133 PPB_Graphics3D_Impl::PPB_Graphics3D_Impl(PluginModule* module) |
| 132 : Resource(module), | 134 : Resource(module), |
| 133 bound_instance_(NULL) { | 135 bound_instance_(NULL) { |
| 134 } | 136 } |
| 135 | 137 |
| 136 const PPB_Graphics3D_Dev* Graphics3D::GetInterface() { | 138 const PPB_Graphics3D_Dev* PPB_Graphics3D_Impl::GetInterface() { |
| 137 return &ppb_graphics3d; | 139 return &ppb_graphics3d; |
| 138 } | 140 } |
| 139 | 141 |
| 140 Graphics3D* Graphics3D::GetCurrent() { | 142 PPB_Graphics3D_Impl* PPB_Graphics3D_Impl::GetCurrent() { |
| 141 return CurrentContextKey::get()->Get(); | 143 return g_current_context_key.Get().Get(); |
| 142 } | 144 } |
| 143 | 145 |
| 144 void Graphics3D::ResetCurrent() { | 146 void PPB_Graphics3D_Impl::ResetCurrent() { |
| 145 CurrentContextKey::get()->Set(NULL); | 147 g_current_context_key.Get().Set(NULL); |
| 146 } | 148 } |
| 147 | 149 |
| 148 Graphics3D::~Graphics3D() { | 150 PPB_Graphics3D_Impl::~PPB_Graphics3D_Impl() { |
| 149 Destroy(); | 151 Destroy(); |
| 150 } | 152 } |
| 151 | 153 |
| 152 bool Graphics3D::Init(PP_Instance instance_id, int32_t config, | 154 PPB_Graphics3D_Impl* PPB_Graphics3D_Impl::AsPPB_Graphics3D_Impl() { |
| 153 const int32_t* attrib_list) { | 155 return this; |
| 156 } |
| 157 |
| 158 bool PPB_Graphics3D_Impl::Init(PP_Instance instance_id, int32_t config, |
| 159 const int32_t* attrib_list) { |
| 154 PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); | 160 PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); |
| 155 if (!instance) { | 161 if (!instance) { |
| 156 return false; | 162 return false; |
| 157 } | 163 } |
| 158 | 164 |
| 159 // Create and initialize the objects required to issue GLES2 calls. | 165 // Create and initialize the objects required to issue GLES2 calls. |
| 160 platform_context_.reset(instance->delegate()->CreateContext3D()); | 166 platform_context_.reset(instance->delegate()->CreateContext3D()); |
| 161 if (!platform_context_.get()) { | 167 if (!platform_context_.get()) { |
| 162 Destroy(); | 168 Destroy(); |
| 163 return false; | 169 return false; |
| 164 } | 170 } |
| 165 | 171 |
| 166 if (!platform_context_->Init()) { | 172 if (!platform_context_->Init()) { |
| 167 Destroy(); | 173 Destroy(); |
| 168 return false; | 174 return false; |
| 169 } | 175 } |
| 170 | 176 |
| 171 gles2_implementation_ = platform_context_->GetGLES2Implementation(); | 177 gles2_implementation_ = platform_context_->GetGLES2Implementation(); |
| 172 DCHECK(gles2_implementation_); | 178 DCHECK(gles2_implementation_); |
| 173 | 179 |
| 174 return true; | 180 return true; |
| 175 } | 181 } |
| 176 | 182 |
| 177 bool Graphics3D::BindToInstance(PluginInstance* new_instance) { | 183 bool PPB_Graphics3D_Impl::BindToInstance(PluginInstance* new_instance) { |
| 178 if (bound_instance_ == new_instance) | 184 if (bound_instance_ == new_instance) |
| 179 return true; // Rebinding the same device, nothing to do. | 185 return true; // Rebinding the same device, nothing to do. |
| 180 if (bound_instance_ && new_instance) | 186 if (bound_instance_ && new_instance) |
| 181 return false; // Can't change a bound device. | 187 return false; // Can't change a bound device. |
| 182 | 188 |
| 183 if (new_instance) { | 189 if (new_instance) { |
| 184 // Resize the backing texture to the size of the instance when it is bound. | 190 // Resize the backing texture to the size of the instance when it is bound. |
| 185 platform_context_->ResizeBackingTexture(new_instance->position().size()); | 191 platform_context_->ResizeBackingTexture(new_instance->position().size()); |
| 186 | 192 |
| 187 // This is a temporary hack. The SwapBuffers is issued to force the resize | 193 // This is a temporary hack. The SwapBuffers is issued to force the resize |
| 188 // to take place before any subsequent rendering. This might lead to a | 194 // to take place before any subsequent rendering. This might lead to a |
| 189 // partially rendered frame being displayed. It is also not thread safe | 195 // partially rendered frame being displayed. It is also not thread safe |
| 190 // since the SwapBuffers is written to the command buffer and that command | 196 // since the SwapBuffers is written to the command buffer and that command |
| 191 // buffer might be written to by another thread. | 197 // buffer might be written to by another thread. |
| 192 // TODO(apatrick): Figure out the semantics of binding and resizing. | 198 // TODO(apatrick): Figure out the semantics of binding and resizing. |
| 193 platform_context_->SwapBuffers(); | 199 platform_context_->SwapBuffers(); |
| 194 } | 200 } |
| 195 | 201 |
| 196 bound_instance_ = new_instance; | 202 bound_instance_ = new_instance; |
| 197 return true; | 203 return true; |
| 198 } | 204 } |
| 199 | 205 |
| 200 bool Graphics3D::MakeCurrent() { | 206 bool PPB_Graphics3D_Impl::MakeCurrent() { |
| 201 if (!platform_context_.get()) | 207 if (!platform_context_.get()) |
| 202 return false; | 208 return false; |
| 203 | 209 |
| 204 CurrentContextKey::get()->Set(this); | 210 g_current_context_key.Get().Set(this); |
| 205 | 211 |
| 206 // TODO(apatrick): Return false on context lost. | 212 // TODO(apatrick): Return false on context lost. |
| 207 return true; | 213 return true; |
| 208 } | 214 } |
| 209 | 215 |
| 210 bool Graphics3D::SwapBuffers() { | 216 bool PPB_Graphics3D_Impl::SwapBuffers() { |
| 211 if (!platform_context_.get()) | 217 if (!platform_context_.get()) |
| 212 return false; | 218 return false; |
| 213 | 219 |
| 214 return platform_context_->SwapBuffers(); | 220 return platform_context_->SwapBuffers(); |
| 215 } | 221 } |
| 216 | 222 |
| 217 unsigned Graphics3D::GetError() { | 223 unsigned PPB_Graphics3D_Impl::GetError() { |
| 218 if (!platform_context_.get()) | 224 if (!platform_context_.get()) |
| 219 return 0; | 225 return 0; |
| 220 | 226 |
| 221 return platform_context_->GetError(); | 227 return platform_context_->GetError(); |
| 222 } | 228 } |
| 223 | 229 |
| 224 void Graphics3D::ResizeBackingTexture(const gfx::Size& size) { | 230 void PPB_Graphics3D_Impl::ResizeBackingTexture(const gfx::Size& size) { |
| 225 if (!platform_context_.get()) | 231 if (!platform_context_.get()) |
| 226 return; | 232 return; |
| 227 | 233 |
| 228 platform_context_->ResizeBackingTexture(size); | 234 platform_context_->ResizeBackingTexture(size); |
| 229 } | 235 } |
| 230 | 236 |
| 231 void Graphics3D::SetSwapBuffersCallback(Callback0::Type* callback) { | 237 void PPB_Graphics3D_Impl::SetSwapBuffersCallback(Callback0::Type* callback) { |
| 232 if (!platform_context_.get()) | 238 if (!platform_context_.get()) |
| 233 return; | 239 return; |
| 234 | 240 |
| 235 platform_context_->SetSwapBuffersCallback(callback); | 241 platform_context_->SetSwapBuffersCallback(callback); |
| 236 } | 242 } |
| 237 | 243 |
| 238 unsigned Graphics3D::GetBackingTextureId() { | 244 unsigned PPB_Graphics3D_Impl::GetBackingTextureId() { |
| 239 if (!platform_context_.get()) | 245 if (!platform_context_.get()) |
| 240 return 0; | 246 return 0; |
| 241 | 247 |
| 242 return platform_context_->GetBackingTextureId(); | 248 return platform_context_->GetBackingTextureId(); |
| 243 } | 249 } |
| 244 | 250 |
| 245 void Graphics3D::Destroy() { | 251 void PPB_Graphics3D_Impl::Destroy() { |
| 246 if (GetCurrent() == this) { | 252 if (GetCurrent() == this) { |
| 247 ResetCurrent(); | 253 ResetCurrent(); |
| 248 } | 254 } |
| 249 | 255 |
| 250 gles2_implementation_ = NULL; | 256 gles2_implementation_ = NULL; |
| 251 | 257 |
| 252 platform_context_.reset(); | 258 platform_context_.reset(); |
| 253 } | 259 } |
| 254 | 260 |
| 255 } // namespace pepper | 261 } // namespace ppapi |
| 262 } // namespace webkit |
| 256 | 263 |
| OLD | NEW |