| 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 <build/build_config.h> | 5 #include <build/build_config.h> |
| 6 | 6 |
| 7 #include "gpu/command_buffer/client/gles2_cmd_helper.h" | 7 #include "gpu/command_buffer/client/gles2_cmd_helper.h" |
| 8 #include "gpu/command_buffer/client/gles2_implementation.h" | 8 #include "gpu/command_buffer/client/gles2_implementation.h" |
| 9 #include "gpu/command_buffer/client/gles2_lib.h" | 9 #include "gpu/command_buffer/client/gles2_lib.h" |
| 10 #include "gpu/command_buffer/common/constants.h" |
| 10 #include "gpu/command_buffer/common/thread_local.h" | 11 #include "gpu/command_buffer/common/thread_local.h" |
| 11 #include "gpu/pgl/command_buffer_pepper.h" | 12 #include "gpu/pgl/command_buffer_pepper.h" |
| 12 #include "gpu/pgl/pgl.h" | 13 #include "gpu/pgl/pgl.h" |
| 13 | 14 |
| 14 namespace { | 15 namespace { |
| 15 const int32 kTransferBufferSize = 512 * 1024; | 16 const int32 kTransferBufferSize = 512 * 1024; |
| 16 | 17 |
| 17 class PGLContextImpl { | 18 class PGLContextImpl { |
| 18 public: | 19 public: |
| 19 PGLContextImpl(NPP npp, | 20 PGLContextImpl(NPP npp, |
| 20 NPDevice* device, | 21 NPDevice* device, |
| 21 NPDeviceContext3D* device_context); | 22 NPDeviceContext3D* device_context); |
| 22 ~PGLContextImpl(); | 23 ~PGLContextImpl(); |
| 23 | 24 |
| 24 // Initlaize a PGL context with a transfer buffer of a particular size. | 25 // Initlaize a PGL context with a transfer buffer of a particular size. |
| 25 bool Initialize(int32 transfer_buffer_size); | 26 PGLBoolean Initialize(int32 transfer_buffer_size); |
| 26 | 27 |
| 27 // Destroy all resources associated with the PGL context. | 28 // Destroy all resources associated with the PGL context. |
| 28 void Destroy(); | 29 void Destroy(); |
| 29 | 30 |
| 30 // Make a PGL context current for the calling thread. | 31 // Make a PGL context current for the calling thread. |
| 31 static bool MakeCurrent(PGLContextImpl* pgl_context); | 32 static PGLBoolean MakeCurrent(PGLContextImpl* pgl_context); |
| 32 | 33 |
| 33 // Display all content rendered since last call to SwapBuffers. | 34 // Display all content rendered since last call to SwapBuffers. |
| 34 bool SwapBuffers(); | 35 PGLBoolean SwapBuffers(); |
| 36 |
| 37 // Get the current error code. |
| 38 PGLInt GetError(); |
| 35 | 39 |
| 36 private: | 40 private: |
| 37 PGLContextImpl(const PGLContextImpl&); | 41 PGLContextImpl(const PGLContextImpl&); |
| 38 void operator=(const PGLContextImpl&); | 42 void operator=(const PGLContextImpl&); |
| 39 | 43 |
| 40 NPP npp_; | 44 NPP npp_; |
| 41 NPDevice* device_; | 45 NPDevice* device_; |
| 42 NPDeviceContext3D* device_context_; | 46 NPDeviceContext3D* device_context_; |
| 43 CommandBufferPepper* command_buffer_; | 47 CommandBufferPepper* command_buffer_; |
| 44 gpu::gles2::GLES2CmdHelper* gles2_helper_; | 48 gpu::gles2::GLES2CmdHelper* gles2_helper_; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 57 command_buffer_(NULL), | 61 command_buffer_(NULL), |
| 58 gles2_helper_(NULL), | 62 gles2_helper_(NULL), |
| 59 transfer_buffer_id_(0), | 63 transfer_buffer_id_(0), |
| 60 gles2_implementation_(NULL) { | 64 gles2_implementation_(NULL) { |
| 61 } | 65 } |
| 62 | 66 |
| 63 PGLContextImpl::~PGLContextImpl() { | 67 PGLContextImpl::~PGLContextImpl() { |
| 64 Destroy(); | 68 Destroy(); |
| 65 } | 69 } |
| 66 | 70 |
| 67 bool PGLContextImpl::Initialize(int32 transfer_buffer_size) { | 71 PGLBoolean PGLContextImpl::Initialize(int32 transfer_buffer_size) { |
| 68 // Create and initialize the objects required to issue GLES2 calls. | 72 // Create and initialize the objects required to issue GLES2 calls. |
| 69 command_buffer_ = new CommandBufferPepper( | 73 command_buffer_ = new CommandBufferPepper( |
| 70 npp_, device_, device_context_); | 74 npp_, device_, device_context_); |
| 71 gles2_helper_ = new gpu::gles2::GLES2CmdHelper(command_buffer_); | 75 gles2_helper_ = new gpu::gles2::GLES2CmdHelper(command_buffer_); |
| 72 if (gles2_helper_->Initialize()) { | 76 if (gles2_helper_->Initialize()) { |
| 73 transfer_buffer_id_ = | 77 transfer_buffer_id_ = |
| 74 command_buffer_->CreateTransferBuffer(kTransferBufferSize); | 78 command_buffer_->CreateTransferBuffer(kTransferBufferSize); |
| 75 gpu::Buffer transfer_buffer = | 79 gpu::Buffer transfer_buffer = |
| 76 command_buffer_->GetTransferBuffer(transfer_buffer_id_); | 80 command_buffer_->GetTransferBuffer(transfer_buffer_id_); |
| 77 if (transfer_buffer.ptr) { | 81 if (transfer_buffer.ptr) { |
| 78 gles2_implementation_ = new gpu::gles2::GLES2Implementation( | 82 gles2_implementation_ = new gpu::gles2::GLES2Implementation( |
| 79 gles2_helper_, | 83 gles2_helper_, |
| 80 transfer_buffer.size, | 84 transfer_buffer.size, |
| 81 transfer_buffer.ptr, | 85 transfer_buffer.ptr, |
| 82 transfer_buffer_id_); | 86 transfer_buffer_id_); |
| 83 return true; | 87 return PGL_TRUE; |
| 84 } | 88 } |
| 85 } | 89 } |
| 86 | 90 |
| 87 // Tear everything down if initialization failed. | 91 // Tear everything down if initialization failed. |
| 88 Destroy(); | 92 Destroy(); |
| 89 return false; | 93 return PGL_FALSE; |
| 90 } | 94 } |
| 91 | 95 |
| 92 void PGLContextImpl::Destroy() { | 96 void PGLContextImpl::Destroy() { |
| 93 delete gles2_implementation_; | 97 delete gles2_implementation_; |
| 94 gles2_implementation_ = NULL; | 98 gles2_implementation_ = NULL; |
| 95 | 99 |
| 96 if (command_buffer_ && transfer_buffer_id_ != 0) { | 100 if (command_buffer_ && transfer_buffer_id_ != 0) { |
| 97 command_buffer_->DestroyTransferBuffer(transfer_buffer_id_); | 101 command_buffer_->DestroyTransferBuffer(transfer_buffer_id_); |
| 98 transfer_buffer_id_ = 0; | 102 transfer_buffer_id_ = 0; |
| 99 } | 103 } |
| 100 | 104 |
| 101 delete gles2_helper_; | 105 delete gles2_helper_; |
| 102 gles2_helper_ = NULL; | 106 gles2_helper_ = NULL; |
| 103 | 107 |
| 104 delete command_buffer_; | 108 delete command_buffer_; |
| 105 command_buffer_ = NULL; | 109 command_buffer_ = NULL; |
| 106 } | 110 } |
| 107 | 111 |
| 108 bool PGLContextImpl::MakeCurrent(PGLContextImpl* pgl_context) { | 112 PGLBoolean PGLContextImpl::MakeCurrent(PGLContextImpl* pgl_context) { |
| 109 if (!g_pgl_context_key) | 113 if (!g_pgl_context_key) |
| 110 return false; | 114 return PGL_FALSE; |
| 111 | 115 |
| 112 gpu::ThreadLocalSetValue(g_pgl_context_key, pgl_context); | 116 gpu::ThreadLocalSetValue(g_pgl_context_key, pgl_context); |
| 113 if (pgl_context) | 117 if (pgl_context) { |
| 114 gles2::SetGLContext(pgl_context->gles2_implementation_); | 118 gles2::SetGLContext(pgl_context->gles2_implementation_); |
| 115 else | 119 |
| 120 // Don't request latest error status from service. Just use the locally |
| 121 // cached information from the last flush. |
| 122 // TODO(apatrick): I'm not sure if this should actually change the |
| 123 // current context if it fails. For now it gets changed even if it fails |
| 124 // becuase making GL calls with a NULL context crashes. |
| 125 if (pgl_context->device_context_->error != NPDeviceContext3DError_NoError) |
| 126 return PGL_FALSE; |
| 127 } |
| 128 else { |
| 116 gles2::SetGLContext(NULL); | 129 gles2::SetGLContext(NULL); |
| 130 } |
| 117 | 131 |
| 118 return true; | 132 return PGL_TRUE; |
| 119 } | 133 } |
| 120 | 134 |
| 121 bool PGLContextImpl::SwapBuffers() { | 135 PGLBoolean PGLContextImpl::SwapBuffers() { |
| 136 // Don't request latest error status from service. Just use the locally cached |
| 137 // information from the last flush. |
| 138 if (device_context_->error != NPDeviceContext3DError_NoError) |
| 139 return PGL_FALSE; |
| 140 |
| 122 gles2_implementation_->SwapBuffers(); | 141 gles2_implementation_->SwapBuffers(); |
| 123 return true; | 142 return PGL_TRUE; |
| 143 } |
| 144 |
| 145 PGLInt PGLContextImpl::GetError() { |
| 146 gpu::CommandBuffer::State state = command_buffer_->GetState(); |
| 147 if (state.error == gpu::error::kNoError) { |
| 148 return PGL_SUCCESS; |
| 149 } else { |
| 150 // All command buffer errors are unrecoverable. The error is treated as a |
| 151 // lost context: destroy the context and create another one. |
| 152 return PGL_CONTEXT_LOST; |
| 153 } |
| 124 } | 154 } |
| 125 } // namespace anonymous | 155 } // namespace anonymous |
| 126 | 156 |
| 127 extern "C" { | 157 extern "C" { |
| 128 | 158 |
| 129 PGLBoolean pglInitialize() { | 159 PGLBoolean pglInitialize() { |
| 130 if (g_pgl_context_key) | 160 if (g_pgl_context_key) |
| 131 return true; | 161 return PGL_TRUE; |
| 132 | 162 |
| 133 gles2::Initialize(); | 163 gles2::Initialize(); |
| 134 g_pgl_context_key = gpu::ThreadLocalAlloc(); | 164 g_pgl_context_key = gpu::ThreadLocalAlloc(); |
| 135 return true; | 165 return PGL_TRUE; |
| 136 } | 166 } |
| 137 | 167 |
| 138 PGLBoolean pglTerminate() { | 168 PGLBoolean pglTerminate() { |
| 139 if (!g_pgl_context_key) | 169 if (!g_pgl_context_key) |
| 140 return true; | 170 return PGL_TRUE; |
| 141 | 171 |
| 142 gpu::ThreadLocalFree(g_pgl_context_key); | 172 gpu::ThreadLocalFree(g_pgl_context_key); |
| 173 g_pgl_context_key = 0; |
| 174 |
| 143 gles2::Terminate(); | 175 gles2::Terminate(); |
| 144 return true; | 176 return PGL_TRUE; |
| 145 } | 177 } |
| 146 | 178 |
| 147 PGLContext pglCreateContext(NPP npp, | 179 PGLContext pglCreateContext(NPP npp, |
| 148 NPDevice* device, | 180 NPDevice* device, |
| 149 NPDeviceContext3D* device_context) { | 181 NPDeviceContext3D* device_context) { |
| 150 if (!g_pgl_context_key) | 182 if (!g_pgl_context_key) |
| 151 return NULL; | 183 return NULL; |
| 152 | 184 |
| 153 PGLContextImpl* pgl_context = new PGLContextImpl( | 185 PGLContextImpl* pgl_context = new PGLContextImpl( |
| 154 npp, device, device_context); | 186 npp, device, device_context); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 168 if (!g_pgl_context_key) | 200 if (!g_pgl_context_key) |
| 169 return NULL; | 201 return NULL; |
| 170 | 202 |
| 171 return static_cast<PGLContext>(gpu::ThreadLocalGetValue(g_pgl_context_key)); | 203 return static_cast<PGLContext>(gpu::ThreadLocalGetValue(g_pgl_context_key)); |
| 172 } | 204 } |
| 173 | 205 |
| 174 PGLBoolean pglSwapBuffers(void) { | 206 PGLBoolean pglSwapBuffers(void) { |
| 175 PGLContextImpl* context = static_cast<PGLContextImpl*>( | 207 PGLContextImpl* context = static_cast<PGLContextImpl*>( |
| 176 pglGetCurrentContext()); | 208 pglGetCurrentContext()); |
| 177 if (!context) | 209 if (!context) |
| 178 return false; | 210 return PGL_FALSE; |
| 179 | 211 |
| 180 return context->SwapBuffers(); | 212 return context->SwapBuffers(); |
| 181 } | 213 } |
| 182 | 214 |
| 183 PGLBoolean pglDestroyContext(PGLContext pgl_context) { | 215 PGLBoolean pglDestroyContext(PGLContext pgl_context) { |
| 184 if (!g_pgl_context_key) | 216 if (!g_pgl_context_key) |
| 185 return NULL; | 217 return PGL_FALSE; |
| 186 | 218 |
| 187 if (!pgl_context) | 219 if (!pgl_context) |
| 188 return false; | 220 return PGL_FALSE; |
| 189 | 221 |
| 190 if (pgl_context == pglGetCurrentContext()) | 222 if (pgl_context == pglGetCurrentContext()) |
| 191 pglMakeCurrent(NULL); | 223 pglMakeCurrent(NULL); |
| 192 | 224 |
| 193 delete static_cast<PGLContextImpl*>(pgl_context); | 225 delete static_cast<PGLContextImpl*>(pgl_context); |
| 194 return true; | 226 return PGL_TRUE; |
| 195 } | 227 } |
| 196 | 228 |
| 229 PGLInt pglGetError() { |
| 230 if (!g_pgl_context_key) |
| 231 return PGL_NOT_INITIALIZED; |
| 232 |
| 233 PGLContextImpl* context = static_cast<PGLContextImpl*>( |
| 234 pglGetCurrentContext()); |
| 235 if (!context) |
| 236 return PGL_BAD_CONTEXT; |
| 237 |
| 238 return context->GetError(); |
| 239 } |
| 197 } // extern "C" | 240 } // extern "C" |
| OLD | NEW |