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 |