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