OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "gpu/command_buffer/service/gles2_cmd_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <vector> | 10 #include <vector> |
11 #include <string> | 11 #include <string> |
12 #include <map> | 12 #include <map> |
13 #include <build/build_config.h> // NOLINT | 13 #include <build/build_config.h> // NOLINT |
14 #include "base/callback.h" | 14 #include "base/callback.h" |
15 #include "base/linked_ptr.h" | 15 #include "base/linked_ptr.h" |
16 #include "base/scoped_ptr.h" | 16 #include "base/scoped_ptr.h" |
| 17 #include "base/weak_ptr.h" |
17 #define GLES2_GPU_SERVICE 1 | 18 #define GLES2_GPU_SERVICE 1 |
18 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 19 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
19 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 20 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
20 #include "gpu/command_buffer/service/buffer_manager.h" | 21 #include "gpu/command_buffer/service/buffer_manager.h" |
21 #include "gpu/command_buffer/service/cmd_buffer_engine.h" | 22 #include "gpu/command_buffer/service/cmd_buffer_engine.h" |
22 #include "gpu/command_buffer/service/context_group.h" | 23 #include "gpu/command_buffer/service/context_group.h" |
23 #include "gpu/command_buffer/service/framebuffer_manager.h" | 24 #include "gpu/command_buffer/service/framebuffer_manager.h" |
24 #include "gpu/command_buffer/service/gl_utils.h" | 25 #include "gpu/command_buffer/service/gl_utils.h" |
25 #include "gpu/command_buffer/service/gles2_cmd_validation.h" | 26 #include "gpu/command_buffer/service/gles2_cmd_validation.h" |
26 #include "gpu/command_buffer/service/id_manager.h" | 27 #include "gpu/command_buffer/service/id_manager.h" |
27 #include "gpu/command_buffer/service/program_manager.h" | 28 #include "gpu/command_buffer/service/program_manager.h" |
28 #include "gpu/command_buffer/service/renderbuffer_manager.h" | 29 #include "gpu/command_buffer/service/renderbuffer_manager.h" |
29 #include "gpu/command_buffer/service/shader_manager.h" | 30 #include "gpu/command_buffer/service/shader_manager.h" |
30 #include "gpu/command_buffer/service/texture_manager.h" | 31 #include "gpu/command_buffer/service/texture_manager.h" |
31 #if defined(UNIT_TEST) | 32 #if defined(UNIT_TEST) |
32 #elif defined(OS_LINUX) | 33 #elif defined(OS_LINUX) |
33 // XWindowWrapper is stubbed out for unit-tests. | 34 // XWindowWrapper is stubbed out for unit-tests. |
34 #include "gpu/command_buffer/service/x_utils.h" | 35 #include "gpu/command_buffer/service/x_utils.h" |
35 #elif defined(OS_MACOSX) | 36 #elif defined(OS_MACOSX) |
36 #include "app/surface/accelerated_surface_mac.h" | 37 #include "app/surface/accelerated_surface_mac.h" |
37 #endif | 38 #endif |
38 | 39 |
| 40 #if !defined(GL_DEPTH24_STENCIL8) |
| 41 #define GL_DEPTH24_STENCIL8 0x88F0 |
| 42 #endif |
| 43 |
39 namespace gpu { | 44 namespace gpu { |
40 namespace gles2 { | 45 namespace gles2 { |
41 | 46 |
| 47 class GLES2DecoderImpl; |
| 48 |
42 // Check that certain assumptions the code makes are true. There are places in | 49 // Check that certain assumptions the code makes are true. There are places in |
43 // the code where shared memory is passed direclty to GL. Example, glUniformiv, | 50 // the code where shared memory is passed direclty to GL. Example, glUniformiv, |
44 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe | 51 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe |
45 // a few others) are 32bits. If they are not 32bits the code will have to change | 52 // a few others) are 32bits. If they are not 32bits the code will have to change |
46 // to call those GL functions with service side memory and then copy the results | 53 // to call those GL functions with service side memory and then copy the results |
47 // to shared memory, converting the sizes. | 54 // to shared memory, converting the sizes. |
48 COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT | 55 COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT |
49 GLint_not_same_size_as_uint32); | 56 GLint_not_same_size_as_uint32); |
50 COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT | 57 COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT |
51 GLint_not_same_size_as_uint32); | 58 GLint_not_same_size_as_uint32); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 const CommandInfo g_command_info[] = { | 107 const CommandInfo g_command_info[] = { |
101 #define GLES2_CMD_OP(name) { \ | 108 #define GLES2_CMD_OP(name) { \ |
102 name::kArgFlags, \ | 109 name::kArgFlags, \ |
103 sizeof(name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \ | 110 sizeof(name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \ |
104 | 111 |
105 GLES2_COMMAND_LIST(GLES2_CMD_OP) | 112 GLES2_COMMAND_LIST(GLES2_CMD_OP) |
106 | 113 |
107 #undef GLES2_CMD_OP | 114 #undef GLES2_CMD_OP |
108 }; | 115 }; |
109 | 116 |
| 117 // This class prevents any GL errors that occur when it is in scope from |
| 118 // being reported to the client. |
| 119 class ScopedGLErrorSuppressor { |
| 120 public: |
| 121 explicit ScopedGLErrorSuppressor(GLES2DecoderImpl* decoder); |
| 122 ~ScopedGLErrorSuppressor(); |
| 123 private: |
| 124 GLES2DecoderImpl* decoder_; |
| 125 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor); |
| 126 }; |
| 127 |
| 128 // Temporarily changes a decoder's bound 2D texture and restore it when this |
| 129 // object goes out of scope. Also temporarily switches to using active texture |
| 130 // unit zero in case the client has changed that to something invalid. |
| 131 class ScopedTexture2DBinder { |
| 132 public: |
| 133 ScopedTexture2DBinder(GLES2DecoderImpl* decoder, GLuint id); |
| 134 ~ScopedTexture2DBinder(); |
| 135 |
| 136 private: |
| 137 GLES2DecoderImpl* decoder_; |
| 138 DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder); |
| 139 }; |
| 140 |
| 141 // Temporarily changes a decoder's bound render buffer and restore it when this |
| 142 // object goes out of scope. |
| 143 class ScopedRenderBufferBinder { |
| 144 public: |
| 145 ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, GLuint id); |
| 146 ~ScopedRenderBufferBinder(); |
| 147 |
| 148 private: |
| 149 GLES2DecoderImpl* decoder_; |
| 150 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder); |
| 151 }; |
| 152 |
| 153 // Temporarily changes a decoder's bound frame buffer and restore it when this |
| 154 // object goes out of scope. |
| 155 class ScopedFrameBufferBinder { |
| 156 public: |
| 157 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id); |
| 158 ~ScopedFrameBufferBinder(); |
| 159 |
| 160 private: |
| 161 GLES2DecoderImpl* decoder_; |
| 162 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder); |
| 163 }; |
| 164 |
| 165 // Encapsulates an OpenGL texture. |
| 166 class Texture { |
| 167 public: |
| 168 explicit Texture(GLES2DecoderImpl* decoder); |
| 169 ~Texture(); |
| 170 |
| 171 // Create a new render texture. |
| 172 void Create(); |
| 173 |
| 174 // Set the initial size and format of a render texture or resize it. |
| 175 bool AllocateStorage(const gfx::Size& size); |
| 176 |
| 177 // Copy the contents of the currently bound frame buffer. |
| 178 void Copy(const gfx::Size& size); |
| 179 |
| 180 // Destroy the render texture. This must be explicitly called before |
| 181 // destroying this object. |
| 182 void Destroy(); |
| 183 |
| 184 GLuint id() const { |
| 185 return id_; |
| 186 } |
| 187 |
| 188 private: |
| 189 GLES2DecoderImpl* decoder_; |
| 190 GLuint id_; |
| 191 DISALLOW_COPY_AND_ASSIGN(Texture); |
| 192 }; |
| 193 |
| 194 // Encapsulates an OpenGL render buffer of any format. |
| 195 class RenderBuffer { |
| 196 public: |
| 197 explicit RenderBuffer(GLES2DecoderImpl* decoder); |
| 198 ~RenderBuffer(); |
| 199 |
| 200 // Create a new render buffer. |
| 201 void Create(); |
| 202 |
| 203 // Set the initial size and format of a render buffer or resize it. |
| 204 bool AllocateStorage(const gfx::Size& size, GLenum format); |
| 205 |
| 206 // Destroy the render buffer. This must be explicitly called before destroying |
| 207 // this object. |
| 208 void Destroy(); |
| 209 |
| 210 GLuint id() const { |
| 211 return id_; |
| 212 } |
| 213 |
| 214 private: |
| 215 GLES2DecoderImpl* decoder_; |
| 216 GLuint id_; |
| 217 DISALLOW_COPY_AND_ASSIGN(RenderBuffer); |
| 218 }; |
| 219 |
| 220 // Encapsulates an OpenGL frame buffer. |
| 221 class FrameBuffer { |
| 222 public: |
| 223 explicit FrameBuffer(GLES2DecoderImpl* decoder); |
| 224 ~FrameBuffer(); |
| 225 |
| 226 // Create a new frame buffer. |
| 227 void Create(); |
| 228 |
| 229 // Attach a color render buffer to a frame buffer. |
| 230 void AttachRenderTexture(Texture* texture); |
| 231 |
| 232 // Attach a depth stencil render buffer to a frame buffer. Note that |
| 233 // this unbinds any currently bound frame buffer. |
| 234 void AttachDepthStencilRenderBuffer(RenderBuffer* render_buffer); |
| 235 |
| 236 // Clear the given attached buffers. |
| 237 void Clear(GLbitfield buffers); |
| 238 |
| 239 // Destroy the frame buffer. This must be explicitly called before destroying |
| 240 // this object. |
| 241 void Destroy(); |
| 242 |
| 243 // See glCheckFramebufferStatusEXT. |
| 244 GLenum CheckStatus(); |
| 245 |
| 246 GLuint id() const { |
| 247 return id_; |
| 248 } |
| 249 |
| 250 private: |
| 251 GLES2DecoderImpl* decoder_; |
| 252 GLuint id_; |
| 253 DISALLOW_COPY_AND_ASSIGN(FrameBuffer); |
| 254 }; |
110 // } // anonymous namespace. | 255 // } // anonymous namespace. |
111 | 256 |
112 GLES2Decoder::GLES2Decoder(ContextGroup* group) | 257 GLES2Decoder::GLES2Decoder(ContextGroup* group) |
113 : group_(group), | 258 : group_(group), |
114 #if defined(UNIT_TEST) | 259 #if defined(UNIT_TEST) |
115 debug_(false) { | 260 debug_(false) { |
116 #elif defined(OS_LINUX) | 261 #elif defined(OS_LINUX) |
117 debug_(false), | 262 debug_(false), |
118 window_(NULL) { | 263 window_(NULL) { |
119 #elif defined(OS_WIN) | 264 #elif defined(OS_WIN) |
120 debug_(false), | 265 debug_(false), |
121 hwnd_(NULL) { | 266 hwnd_(NULL) { |
122 #else | 267 #else |
123 debug_(false) { | 268 debug_(false) { |
124 #endif | 269 #endif |
125 } | 270 } |
126 | 271 |
127 GLES2Decoder::~GLES2Decoder() { | 272 GLES2Decoder::~GLES2Decoder() { |
128 } | 273 } |
129 | 274 |
130 // This class implements GLES2Decoder so we don't have to expose all the GLES2 | 275 // This class implements GLES2Decoder so we don't have to expose all the GLES2 |
131 // cmd stuff to outside this class. | 276 // cmd stuff to outside this class. |
132 class GLES2DecoderImpl : public GLES2Decoder { | 277 class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, |
| 278 public GLES2Decoder { |
133 public: | 279 public: |
134 explicit GLES2DecoderImpl(ContextGroup* group); | 280 explicit GLES2DecoderImpl(ContextGroup* group); |
135 | 281 |
136 // Info about Vertex Attributes. This is used to track what the user currently | 282 // Info about Vertex Attributes. This is used to track what the user currently |
137 // has bound on each Vertex Attribute so that checking can be done at | 283 // has bound on each Vertex Attribute so that checking can be done at |
138 // glDrawXXX time. | 284 // glDrawXXX time. |
139 class VertexAttribInfo { | 285 class VertexAttribInfo { |
140 public: | 286 public: |
141 VertexAttribInfo() | 287 VertexAttribInfo() |
142 : enabled_(false), | 288 : enabled_(false), |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 | 349 |
204 // Overridden from AsyncAPIInterface. | 350 // Overridden from AsyncAPIInterface. |
205 virtual Error DoCommand(unsigned int command, | 351 virtual Error DoCommand(unsigned int command, |
206 unsigned int arg_count, | 352 unsigned int arg_count, |
207 const void* args); | 353 const void* args); |
208 | 354 |
209 // Overridden from AsyncAPIInterface. | 355 // Overridden from AsyncAPIInterface. |
210 virtual const char* GetCommandName(unsigned int command_id) const; | 356 virtual const char* GetCommandName(unsigned int command_id) const; |
211 | 357 |
212 // Overridden from GLES2Decoder. | 358 // Overridden from GLES2Decoder. |
213 virtual bool Initialize(); | 359 virtual bool Initialize(GLES2Decoder* parent, |
| 360 const gfx::Size& size, |
| 361 uint32 parent_client_texture_id); |
214 virtual void Destroy(); | 362 virtual void Destroy(); |
| 363 virtual void ResizeOffscreenFrameBuffer(const gfx::Size& size); |
215 virtual bool MakeCurrent(); | 364 virtual bool MakeCurrent(); |
216 virtual uint32 GetServiceIdForTesting(uint32 client_id); | 365 virtual uint32 GetServiceIdForTesting(uint32 client_id); |
217 virtual GLES2Util* GetGLES2Util() { return &util_; } | 366 virtual GLES2Util* GetGLES2Util() { return &util_; } |
218 | 367 |
219 #if defined(OS_MACOSX) | 368 #if defined(OS_MACOSX) |
220 // Overridden from GLES2Decoder. | 369 // Overridden from GLES2Decoder. |
221 | 370 |
222 // The recommended usage is to call SetWindowSizeForIOSurface() first, and if | 371 // The recommended usage is to call SetWindowSizeForIOSurface() first, and if |
223 // that returns 0, try calling SetWindowSizeForTransportDIB(). A return value | 372 // that returns 0, try calling SetWindowSizeForTransportDIB(). A return value |
224 // of 0 from SetWindowSizeForIOSurface() might mean the IOSurface API is not | 373 // of 0 from SetWindowSizeForIOSurface() might mean the IOSurface API is not |
225 // available, which is true if you are not running on Max OS X 10.6 or later. | 374 // available, which is true if you are not running on Max OS X 10.6 or later. |
226 // If SetWindowSizeForTransportDIB() also returns a NULL handle, then an | 375 // If SetWindowSizeForTransportDIB() also returns a NULL handle, then an |
227 // error has occured. | 376 // error has occured. |
228 virtual uint64 SetWindowSizeForIOSurface(int32 width, int32 height); | 377 virtual uint64 SetWindowSizeForIOSurface(int32 width, int32 height); |
229 virtual TransportDIB::Handle SetWindowSizeForTransportDIB(int32 width, | 378 virtual TransportDIB::Handle SetWindowSizeForTransportDIB(int32 width, |
230 int32 height); | 379 int32 height); |
231 // |allocator| sends a message to the renderer asking for a new | 380 // |allocator| sends a message to the renderer asking for a new |
232 // TransportDIB big enough to hold the rendered bits. The parameters to the | 381 // TransportDIB big enough to hold the rendered bits. The parameters to the |
233 // call back are the size of the DIB and the handle (filled in on return). | 382 // call back are the size of the DIB and the handle (filled in on return). |
234 virtual void SetTransportDIBAllocAndFree( | 383 virtual void SetTransportDIBAllocAndFree( |
235 Callback2<size_t, TransportDIB::Handle*>::Type* allocator, | 384 Callback2<size_t, TransportDIB::Handle*>::Type* allocator, |
236 Callback1<TransportDIB::Id>::Type* deallocator); | 385 Callback1<TransportDIB::Id>::Type* deallocator); |
237 #endif | 386 #endif |
238 | 387 |
239 virtual void SetSwapBuffersCallback(Callback0::Type* callback); | 388 virtual void SetSwapBuffersCallback(Callback0::Type* callback); |
240 | 389 |
241 private: | 390 private: |
| 391 friend class ScopedGLErrorSuppressor; |
| 392 friend class ScopedTexture2DBinder; |
| 393 friend class ScopedFrameBufferBinder; |
| 394 friend class ScopedRenderBufferBinder; |
| 395 friend class RenderBuffer; |
| 396 friend class FrameBuffer; |
| 397 |
242 // State associated with each texture unit. | 398 // State associated with each texture unit. |
243 struct TextureUnit { | 399 struct TextureUnit { |
244 TextureUnit() : bind_target(GL_TEXTURE_2D) { } | 400 TextureUnit() : bind_target(GL_TEXTURE_2D) { } |
245 | 401 |
246 // The last target that was bound to this texture unit. | 402 // The last target that was bound to this texture unit. |
247 GLenum bind_target; | 403 GLenum bind_target; |
248 | 404 |
249 // texture currently bound to this unit's GL_TEXTURE_2D with glBindTexture | 405 // texture currently bound to this unit's GL_TEXTURE_2D with glBindTexture |
250 TextureManager::TextureInfo::Ref bound_texture_2d; | 406 TextureManager::TextureInfo::Ref bound_texture_2d; |
251 | 407 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 | 458 |
303 #if defined(OS_WIN) | 459 #if defined(OS_WIN) |
304 static bool InitializeOneOff(bool anti_aliased); | 460 static bool InitializeOneOff(bool anti_aliased); |
305 #endif | 461 #endif |
306 | 462 |
307 | 463 |
308 bool InitPlatformSpecific(); | 464 bool InitPlatformSpecific(); |
309 static bool InitGlew(); | 465 static bool InitGlew(); |
310 void DestroyPlatformSpecific(); | 466 void DestroyPlatformSpecific(); |
311 | 467 |
| 468 bool UpdateOffscreenFrameBufferSize(); |
| 469 |
312 // Template to help call glGenXXX functions. | 470 // Template to help call glGenXXX functions. |
313 template <void gl_gen_function(GLES2DecoderImpl*, GLsizei, GLuint*)> | 471 template <void gl_gen_function(GLES2DecoderImpl*, GLsizei, GLuint*)> |
314 bool GenGLObjects(GLsizei n, const GLuint* client_ids) { | 472 bool GenGLObjects(GLsizei n, const GLuint* client_ids) { |
315 DCHECK_GE(n, 0); | 473 DCHECK_GE(n, 0); |
316 if (!ValidateIdsAreUnused(n, client_ids)) { | 474 if (!ValidateIdsAreUnused(n, client_ids)) { |
317 return false; | 475 return false; |
318 } | 476 } |
319 scoped_array<GLuint>temp(new GLuint[n]); | 477 scoped_array<GLuint>temp(new GLuint[n]); |
320 gl_gen_function(this, n, temp.get()); | 478 gl_gen_function(this, n, temp.get()); |
321 return RegisterObjects(n, client_ids, temp.get()); | 479 return RegisterObjects(n, client_ids, temp.get()); |
(...skipping 14 matching lines...) Expand all Loading... |
336 | 494 |
337 // Register client ids with generated service ids. | 495 // Register client ids with generated service ids. |
338 bool RegisterObjects( | 496 bool RegisterObjects( |
339 GLsizei n, const GLuint* client_ids, const GLuint* service_ids); | 497 GLsizei n, const GLuint* client_ids, const GLuint* service_ids); |
340 | 498 |
341 // Unregisters client ids with service ids. | 499 // Unregisters client ids with service ids. |
342 void UnregisterObjects( | 500 void UnregisterObjects( |
343 GLsizei n, const GLuint* client_ids, GLuint* service_ids); | 501 GLsizei n, const GLuint* client_ids, GLuint* service_ids); |
344 | 502 |
345 // Creates a TextureInfo for the given texture. | 503 // Creates a TextureInfo for the given texture. |
346 void CreateTextureInfo(GLuint texture) { | 504 TextureManager::TextureInfo* CreateTextureInfo(GLuint texture) { |
347 texture_manager()->CreateTextureInfo(texture); | 505 return texture_manager()->CreateTextureInfo(texture); |
348 } | 506 } |
349 | 507 |
350 // Gets the texture info for the given texture. Returns NULL if none exists. | 508 // Gets the texture info for the given texture. Returns NULL if none exists. |
351 TextureManager::TextureInfo* GetTextureInfo(GLuint texture) { | 509 TextureManager::TextureInfo* GetTextureInfo(GLuint texture) { |
352 TextureManager::TextureInfo* info = | 510 TextureManager::TextureInfo* info = |
353 texture_manager()->GetTextureInfo(texture); | 511 texture_manager()->GetTextureInfo(texture); |
354 return (info && !info->IsDeleted()) ? info : NULL; | 512 return (info && !info->IsDeleted()) ? info : NULL; |
355 } | 513 } |
356 | 514 |
357 // Deletes the texture info for the given texture. | 515 // Deletes the texture info for the given texture. |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 void DoGetShaderSource( | 712 void DoGetShaderSource( |
555 GLuint shader, GLsizei bufsize, GLsizei* length, char* dst); | 713 GLuint shader, GLsizei bufsize, GLsizei* length, char* dst); |
556 | 714 |
557 // Wrapper for glLinkProgram | 715 // Wrapper for glLinkProgram |
558 void DoLinkProgram(GLuint program); | 716 void DoLinkProgram(GLuint program); |
559 | 717 |
560 // Wrapper for glRenderbufferStorage. | 718 // Wrapper for glRenderbufferStorage. |
561 void DoRenderbufferStorage( | 719 void DoRenderbufferStorage( |
562 GLenum target, GLenum internalformat, GLsizei width, GLsizei height); | 720 GLenum target, GLenum internalformat, GLsizei width, GLsizei height); |
563 | 721 |
564 // Swaps the buffers (copies/renders to the current window). | |
565 void DoSwapBuffers(); | |
566 | |
567 // Wrappers for glTexParameter functions. | 722 // Wrappers for glTexParameter functions. |
568 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param); | 723 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param); |
569 void DoTexParameteri(GLenum target, GLenum pname, GLint param); | 724 void DoTexParameteri(GLenum target, GLenum pname, GLint param); |
570 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params); | 725 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params); |
571 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params); | 726 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params); |
572 | 727 |
573 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2 | 728 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2 |
574 // spec only these 2 functions can be used to set sampler uniforms. | 729 // spec only these 2 functions can be used to set sampler uniforms. |
575 void DoUniform1i(GLint location, GLint v0); | 730 void DoUniform1i(GLint location, GLint v0); |
576 void DoUniform1iv(GLint location, GLsizei count, const GLint *value); | 731 void DoUniform1iv(GLint location, GLsizei count, const GLint *value); |
577 | 732 |
578 // Wrapper for glUseProgram | 733 // Wrapper for glUseProgram |
579 void DoUseProgram(GLuint program); | 734 void DoUseProgram(GLuint program); |
580 | 735 |
581 // Gets the GLError through our wrapper. | 736 // Gets the GLError through our wrapper. |
582 GLenum GetGLError(); | 737 GLenum GetGLError(); |
583 | 738 |
584 // Sets our wrapper for the GLError. | 739 // Sets our wrapper for the GLError. |
585 void SetGLError(GLenum error); | 740 void SetGLError(GLenum error); |
586 | 741 |
587 // Copies the real GL errors to the wrapper. This is so we can | 742 // Copies the real GL errors to the wrapper. This is so we can |
588 // make sure there are no native GL errors before calling some GL function | 743 // make sure there are no native GL errors before calling some GL function |
589 // so that on return we know any error generated was for that specific | 744 // so that on return we know any error generated was for that specific |
590 // command. | 745 // command. |
591 void CopyRealGLErrorsToWrapper(); | 746 void CopyRealGLErrorsToWrapper(); |
592 | 747 |
| 748 // Clear all real GL errors. This is to prevent the client from seeing any |
| 749 // errors caused by GL calls that it was not responsible for issuing. |
| 750 void ClearRealGLErrors(); |
| 751 |
593 // Checks if the current program and vertex attributes are valid for drawing. | 752 // Checks if the current program and vertex attributes are valid for drawing. |
594 bool IsDrawValid(GLuint max_vertex_accessed); | 753 bool IsDrawValid(GLuint max_vertex_accessed); |
595 | 754 |
596 void SetBlackTextureForNonRenderableTextures( | 755 void SetBlackTextureForNonRenderableTextures( |
597 bool* has_non_renderable_textures); | 756 bool* has_non_renderable_textures); |
598 void RestoreStateForNonRenderableTextures(); | 757 void RestoreStateForNonRenderableTextures(); |
599 | 758 |
600 // Gets the buffer id for a given target. | 759 // Gets the buffer id for a given target. |
601 BufferManager::BufferInfo* GetBufferInfoForTarget(GLenum target) { | 760 BufferManager::BufferInfo* GetBufferInfoForTarget(GLenum target) { |
602 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER); | 761 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 // typesafe way. | 806 // typesafe way. |
648 #define GLES2_CMD_OP(name) \ | 807 #define GLES2_CMD_OP(name) \ |
649 Error Handle ## name( \ | 808 Error Handle ## name( \ |
650 uint32 immediate_data_size, \ | 809 uint32 immediate_data_size, \ |
651 const gles2::name& args); \ | 810 const gles2::name& args); \ |
652 | 811 |
653 GLES2_COMMAND_LIST(GLES2_CMD_OP) | 812 GLES2_COMMAND_LIST(GLES2_CMD_OP) |
654 | 813 |
655 #undef GLES2_CMD_OP | 814 #undef GLES2_CMD_OP |
656 | 815 |
| 816 // A parent decoder can access this decoders saved offscreen frame buffer. |
| 817 // The parent pointer is reset if the parent is destroyed. |
| 818 base::WeakPtr<GLES2DecoderImpl> parent_; |
| 819 |
| 820 // Width and height to which an offscreen frame buffer should be resized on |
| 821 // the next call to SwapBuffers. |
| 822 gfx::Size pending_size_; |
| 823 |
| 824 // Width and height of a decoder that renders to an offscreen frame buffer. |
| 825 gfx::Size current_size_; |
| 826 |
657 // Current GL error bits. | 827 // Current GL error bits. |
658 uint32 error_bits_; | 828 uint32 error_bits_; |
659 | 829 |
660 // Util to help with GL. | 830 // Util to help with GL. |
661 GLES2Util util_; | 831 GLES2Util util_; |
662 | 832 |
663 // pack alignment as last set by glPixelStorei | 833 // pack alignment as last set by glPixelStorei |
664 GLint pack_alignment_; | 834 GLint pack_alignment_; |
665 | 835 |
666 // unpack alignment as last set by glPixelStorei | 836 // unpack alignment as last set by glPixelStorei |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 static int pixel_format_; | 877 static int pixel_format_; |
708 HDC gl_device_context_; | 878 HDC gl_device_context_; |
709 HGLRC gl_context_; | 879 HGLRC gl_context_; |
710 HPBUFFERARB pbuffer_; | 880 HPBUFFERARB pbuffer_; |
711 #elif defined(OS_MACOSX) | 881 #elif defined(OS_MACOSX) |
712 AcceleratedSurface surface_; | 882 AcceleratedSurface surface_; |
713 #endif | 883 #endif |
714 | 884 |
715 bool anti_aliased_; | 885 bool anti_aliased_; |
716 | 886 |
| 887 // The offscreen frame buffer that the client renders to. |
| 888 scoped_ptr<FrameBuffer> offscreen_target_frame_buffer_; |
| 889 scoped_ptr<Texture> offscreen_target_color_texture_; |
| 890 scoped_ptr<RenderBuffer> offscreen_target_depth_stencil_render_buffer_; |
| 891 |
| 892 // The copy that is saved when SwapBuffers is called. |
| 893 scoped_ptr<Texture> offscreen_saved_color_texture_; |
| 894 |
| 895 // A frame buffer used for rendering to render textures and render buffers |
| 896 // without concern about any state the client might have changed on the frame |
| 897 // buffers it has access to. |
| 898 scoped_ptr<FrameBuffer> temporary_frame_buffer_; |
| 899 |
717 scoped_ptr<Callback0::Type> swap_buffers_callback_; | 900 scoped_ptr<Callback0::Type> swap_buffers_callback_; |
718 | 901 |
719 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); | 902 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); |
720 }; | 903 }; |
721 | 904 |
| 905 ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(GLES2DecoderImpl* decoder) |
| 906 : decoder_(decoder) { |
| 907 decoder_->CopyRealGLErrorsToWrapper(); |
| 908 } |
| 909 |
| 910 ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() { |
| 911 decoder_->ClearRealGLErrors(); |
| 912 } |
| 913 |
| 914 ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder, |
| 915 GLuint id) |
| 916 : decoder_(decoder) { |
| 917 ScopedGLErrorSuppressor suppressor(decoder_); |
| 918 |
| 919 // TODO(apatrick): Check if there are any other states that need to be reset |
| 920 // before binding a new texture. |
| 921 glActiveTexture(GL_TEXTURE0); |
| 922 glBindTexture(GL_TEXTURE_2D, id); |
| 923 } |
| 924 |
| 925 ScopedTexture2DBinder::~ScopedTexture2DBinder() { |
| 926 ScopedGLErrorSuppressor suppressor(decoder_); |
| 927 GLES2DecoderImpl::TextureUnit& info = decoder_->texture_units_[0]; |
| 928 GLuint last_id; |
| 929 if (info.bound_texture_2d) |
| 930 last_id = info.bound_texture_2d->texture_id(); |
| 931 else |
| 932 last_id = 0; |
| 933 |
| 934 glBindTexture(GL_TEXTURE_2D, last_id); |
| 935 glActiveTexture(GL_TEXTURE0 + decoder_->active_texture_unit_); |
| 936 } |
| 937 |
| 938 ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, |
| 939 GLuint id) |
| 940 : decoder_(decoder) { |
| 941 ScopedGLErrorSuppressor suppressor(decoder_); |
| 942 glBindRenderbufferEXT(GL_RENDERBUFFER, id); |
| 943 } |
| 944 |
| 945 ScopedRenderBufferBinder::~ScopedRenderBufferBinder() { |
| 946 ScopedGLErrorSuppressor suppressor(decoder_); |
| 947 glBindRenderbufferEXT(GL_RENDERBUFFER, decoder_->bound_renderbuffer_); |
| 948 } |
| 949 |
| 950 ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, |
| 951 GLuint id) |
| 952 : decoder_(decoder) { |
| 953 ScopedGLErrorSuppressor suppressor(decoder_); |
| 954 glBindFramebufferEXT(GL_FRAMEBUFFER, id); |
| 955 } |
| 956 |
| 957 ScopedFrameBufferBinder::~ScopedFrameBufferBinder() { |
| 958 ScopedGLErrorSuppressor suppressor(decoder_); |
| 959 if (decoder_->bound_framebuffer_ == 0 && |
| 960 decoder_->offscreen_target_frame_buffer_.get()) { |
| 961 glBindFramebufferEXT(GL_FRAMEBUFFER, |
| 962 decoder_->offscreen_target_frame_buffer_->id()); |
| 963 } else { |
| 964 glBindFramebufferEXT(GL_FRAMEBUFFER, decoder_->bound_framebuffer_); |
| 965 } |
| 966 } |
| 967 |
| 968 Texture::Texture(GLES2DecoderImpl* decoder) |
| 969 : decoder_(decoder), |
| 970 id_(0) { |
| 971 } |
| 972 |
| 973 Texture::~Texture() { |
| 974 // This does not destroy the render texture because that would require that |
| 975 // the associated GL context was current. Just check that it was explicitly |
| 976 // destroyed. |
| 977 DCHECK_EQ(id_, 0u); |
| 978 } |
| 979 |
| 980 void Texture::Create() { |
| 981 ScopedGLErrorSuppressor suppressor(decoder_); |
| 982 Destroy(); |
| 983 glGenTextures(1, &id_); |
| 984 } |
| 985 |
| 986 bool Texture::AllocateStorage(const gfx::Size& size) { |
| 987 DCHECK_NE(id_, 0u); |
| 988 ScopedGLErrorSuppressor suppressor(decoder_); |
| 989 ScopedTexture2DBinder binder(decoder_, id_); |
| 990 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 991 glTexParameteri( |
| 992 GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 993 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 994 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 995 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); |
| 996 |
| 997 glTexImage2D(GL_TEXTURE_2D, |
| 998 0, // mip level |
| 999 GL_RGBA, |
| 1000 size.width(), |
| 1001 size.height(), |
| 1002 0, // border |
| 1003 GL_RGBA, |
| 1004 GL_UNSIGNED_BYTE, |
| 1005 NULL); |
| 1006 |
| 1007 return glGetError() == GL_NO_ERROR; |
| 1008 } |
| 1009 |
| 1010 void Texture::Copy(const gfx::Size& size) { |
| 1011 DCHECK_NE(id_, 0u); |
| 1012 ScopedGLErrorSuppressor suppressor(decoder_); |
| 1013 ScopedTexture2DBinder binder(decoder_, id_); |
| 1014 glCopyTexImage2D(GL_TEXTURE_2D, |
| 1015 0, // level |
| 1016 GL_RGBA, |
| 1017 0, 0, |
| 1018 size.width(), |
| 1019 size.height(), |
| 1020 0); // border |
| 1021 } |
| 1022 |
| 1023 void Texture::Destroy() { |
| 1024 if (id_ != 0) { |
| 1025 ScopedGLErrorSuppressor suppressor(decoder_); |
| 1026 glDeleteTextures(1, &id_); |
| 1027 id_ = 0; |
| 1028 } |
| 1029 } |
| 1030 |
| 1031 RenderBuffer::RenderBuffer(GLES2DecoderImpl* decoder) |
| 1032 : decoder_(decoder), |
| 1033 id_(0) { |
| 1034 } |
| 1035 |
| 1036 RenderBuffer::~RenderBuffer() { |
| 1037 // This does not destroy the render buffer because that would require that |
| 1038 // the associated GL context was current. Just check that it was explicitly |
| 1039 // destroyed. |
| 1040 DCHECK_EQ(id_, 0u); |
| 1041 } |
| 1042 |
| 1043 void RenderBuffer::Create() { |
| 1044 ScopedGLErrorSuppressor suppressor(decoder_); |
| 1045 Destroy(); |
| 1046 glGenRenderbuffersEXT(1, &id_); |
| 1047 } |
| 1048 |
| 1049 bool RenderBuffer::AllocateStorage(const gfx::Size& size, GLenum format) { |
| 1050 ScopedGLErrorSuppressor suppressor(decoder_); |
| 1051 ScopedRenderBufferBinder binder(decoder_, id_); |
| 1052 glRenderbufferStorageEXT(GL_RENDERBUFFER, |
| 1053 format, |
| 1054 size.width(), |
| 1055 size.height()); |
| 1056 return glGetError() == GL_NO_ERROR; |
| 1057 } |
| 1058 |
| 1059 void RenderBuffer::Destroy() { |
| 1060 if (id_ != 0) { |
| 1061 ScopedGLErrorSuppressor suppressor(decoder_); |
| 1062 glDeleteRenderbuffersEXT(1, &id_); |
| 1063 id_ = 0; |
| 1064 } |
| 1065 } |
| 1066 |
| 1067 FrameBuffer::FrameBuffer(GLES2DecoderImpl* decoder) |
| 1068 : decoder_(decoder), |
| 1069 id_(0) { |
| 1070 } |
| 1071 |
| 1072 FrameBuffer::~FrameBuffer() { |
| 1073 // This does not destroy the frame buffer because that would require that |
| 1074 // the associated GL context was current. Just check that it was explicitly |
| 1075 // destroyed. |
| 1076 DCHECK_EQ(id_, 0u); |
| 1077 } |
| 1078 |
| 1079 void FrameBuffer::Create() { |
| 1080 ScopedGLErrorSuppressor suppressor(decoder_); |
| 1081 Destroy(); |
| 1082 glGenFramebuffersEXT(1, &id_); |
| 1083 } |
| 1084 |
| 1085 void FrameBuffer::AttachRenderTexture(Texture* texture) { |
| 1086 DCHECK_NE(id_, 0u); |
| 1087 ScopedGLErrorSuppressor suppressor(decoder_); |
| 1088 ScopedFrameBufferBinder binder(decoder_, id_); |
| 1089 GLuint attach_id = texture ? texture->id() : 0; |
| 1090 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, |
| 1091 GL_COLOR_ATTACHMENT0, |
| 1092 GL_TEXTURE_2D, |
| 1093 attach_id, |
| 1094 0); |
| 1095 } |
| 1096 |
| 1097 void FrameBuffer::AttachDepthStencilRenderBuffer(RenderBuffer* render_buffer) { |
| 1098 DCHECK_NE(id_, 0u); |
| 1099 ScopedGLErrorSuppressor suppressor(decoder_); |
| 1100 ScopedFrameBufferBinder binder(decoder_, id_); |
| 1101 GLuint attach_id = render_buffer ? render_buffer->id() : 0; |
| 1102 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, |
| 1103 GL_DEPTH_ATTACHMENT, |
| 1104 GL_RENDERBUFFER, |
| 1105 attach_id); |
| 1106 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, |
| 1107 GL_STENCIL_ATTACHMENT, |
| 1108 GL_RENDERBUFFER, |
| 1109 attach_id); |
| 1110 } |
| 1111 |
| 1112 void FrameBuffer::Clear(GLbitfield buffers) { |
| 1113 ScopedGLErrorSuppressor suppressor(decoder_); |
| 1114 ScopedFrameBufferBinder binder(decoder_, id_); |
| 1115 glClear(buffers); |
| 1116 } |
| 1117 |
| 1118 void FrameBuffer::Destroy() { |
| 1119 if (id_ != 0) { |
| 1120 ScopedGLErrorSuppressor suppressor(decoder_); |
| 1121 glDeleteFramebuffersEXT(1, &id_); |
| 1122 id_ = 0; |
| 1123 } |
| 1124 } |
| 1125 |
| 1126 GLenum FrameBuffer::CheckStatus() { |
| 1127 DCHECK_NE(id_, 0u); |
| 1128 ScopedGLErrorSuppressor suppressor(decoder_); |
| 1129 ScopedFrameBufferBinder binder(decoder_, id_); |
| 1130 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
| 1131 } |
| 1132 |
722 GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) { | 1133 GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) { |
723 return new GLES2DecoderImpl(group); | 1134 return new GLES2DecoderImpl(group); |
724 } | 1135 } |
725 | 1136 |
726 #if defined(UNIT_TEST) | 1137 #if defined(UNIT_TEST) |
727 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) | 1138 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) |
728 #elif defined(OS_WIN) | 1139 #elif defined(OS_WIN) |
729 int GLES2DecoderImpl::pixel_format_; | 1140 int GLES2DecoderImpl::pixel_format_; |
730 #endif | 1141 #endif |
731 | 1142 |
(...skipping 11 matching lines...) Expand all Loading... |
743 #if defined(UNIT_TEST) | 1154 #if defined(UNIT_TEST) |
744 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) | 1155 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) |
745 #elif defined(OS_WIN) | 1156 #elif defined(OS_WIN) |
746 gl_device_context_(NULL), | 1157 gl_device_context_(NULL), |
747 gl_context_(NULL), | 1158 gl_context_(NULL), |
748 pbuffer_(NULL), | 1159 pbuffer_(NULL), |
749 #endif | 1160 #endif |
750 anti_aliased_(false) { | 1161 anti_aliased_(false) { |
751 } | 1162 } |
752 | 1163 |
753 bool GLES2DecoderImpl::Initialize() { | 1164 bool GLES2DecoderImpl::Initialize(GLES2Decoder* parent, |
| 1165 const gfx::Size& size, |
| 1166 uint32 parent_client_texture_id) { |
| 1167 // Keep only a weak pointer to the parent so we don't unmap its client |
| 1168 // frame buffer is after it has been destroyed. |
| 1169 if (parent) |
| 1170 parent_ = static_cast<GLES2DecoderImpl*>(parent)->AsWeakPtr(); |
| 1171 |
| 1172 pending_size_ = size; |
| 1173 |
754 if (!InitPlatformSpecific()) { | 1174 if (!InitPlatformSpecific()) { |
755 Destroy(); | 1175 Destroy(); |
756 return false; | 1176 return false; |
757 } | 1177 } |
| 1178 |
758 if (!MakeCurrent()) { | 1179 if (!MakeCurrent()) { |
759 Destroy(); | 1180 Destroy(); |
760 return false; | 1181 return false; |
761 } | 1182 } |
762 | 1183 |
763 // This happens in InitializeOneOff in windows. TODO(apatrick): generalize to | 1184 // This happens in InitializeOneOff in windows. TODO(apatrick): generalize to |
764 // other platforms. | 1185 // other platforms. |
765 #if !defined(OS_WIN) | 1186 #if !defined(OS_WIN) |
766 if (!InitGlew()) { | 1187 if (!InitGlew()) { |
767 Destroy(); | 1188 Destroy(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, | 1220 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, |
800 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, | 1221 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, |
801 }; | 1222 }; |
802 for (size_t ii = 0; ii < arraysize(faces); ++ii) { | 1223 for (size_t ii = 0; ii < arraysize(faces); ++ii) { |
803 glTexImage2D(faces[ii], 0, GL_RGBA, 1, 1, 0, GL_RGBA, | 1224 glTexImage2D(faces[ii], 0, GL_RGBA, 1, 1, 0, GL_RGBA, |
804 GL_UNSIGNED_BYTE, black); | 1225 GL_UNSIGNED_BYTE, black); |
805 } | 1226 } |
806 glBindTexture(GL_TEXTURE_CUBE_MAP, 0); | 1227 glBindTexture(GL_TEXTURE_CUBE_MAP, 0); |
807 CHECK_GL_ERROR(); | 1228 CHECK_GL_ERROR(); |
808 | 1229 |
| 1230 if (size.width() > 0 && size.height() > 0) { |
| 1231 // Create the target frame buffer. This is the one that the client renders |
| 1232 // directly to. |
| 1233 offscreen_target_frame_buffer_.reset(new FrameBuffer(this)); |
| 1234 offscreen_target_frame_buffer_->Create(); |
| 1235 offscreen_target_color_texture_.reset(new Texture(this)); |
| 1236 offscreen_target_color_texture_->Create(); |
| 1237 offscreen_target_depth_stencil_render_buffer_.reset( |
| 1238 new RenderBuffer(this)); |
| 1239 offscreen_target_depth_stencil_render_buffer_->Create(); |
| 1240 |
| 1241 // Create the saved offscreen texture. The target frame buffer is copied |
| 1242 // here when SwapBuffers is called. |
| 1243 offscreen_saved_color_texture_.reset(new Texture(this)); |
| 1244 offscreen_saved_color_texture_->Create(); |
| 1245 |
| 1246 // Create the temporary frame buffer, used to operate on render textures |
| 1247 // without concern for state the client might have changed on the frame |
| 1248 // buffers it has access to, like the clear color and the color mask. |
| 1249 temporary_frame_buffer_.reset(new FrameBuffer(this)); |
| 1250 temporary_frame_buffer_->Create(); |
| 1251 |
| 1252 // Map the ID of the saved offscreen texture into the parent so that |
| 1253 // it can reference it. |
| 1254 if (parent_) { |
| 1255 GLuint service_id = offscreen_saved_color_texture_->id(); |
| 1256 parent_->id_manager()->AddMapping(parent_client_texture_id, |
| 1257 service_id); |
| 1258 TextureManager::TextureInfo* info = |
| 1259 parent_->CreateTextureInfo(service_id); |
| 1260 parent_->texture_manager()->SetInfoTarget(info, GL_TEXTURE_2D); |
| 1261 } |
| 1262 |
| 1263 // Allocate the render buffers at their initial size and check the status |
| 1264 // of the frame buffers is okay. |
| 1265 if (!UpdateOffscreenFrameBufferSize()) { |
| 1266 DLOG(ERROR) << "Could not allocate offscreen buffer storage."; |
| 1267 Destroy(); |
| 1268 return false; |
| 1269 } |
| 1270 |
| 1271 // Bind to the new default frame buffer (the offscreen target frame buffer). |
| 1272 // This should now be associated with ID zero. |
| 1273 DoBindFramebuffer(GL_FRAMEBUFFER, 0); |
| 1274 } |
| 1275 |
809 return true; | 1276 return true; |
810 } | 1277 } |
811 | 1278 |
812 // TODO(kbr): the use of this anonymous namespace core dumps the | 1279 // TODO(kbr): the use of this anonymous namespace core dumps the |
813 // linker on Mac OS X 10.6 when the symbol ordering file is used | 1280 // linker on Mac OS X 10.6 when the symbol ordering file is used |
814 // namespace { | 1281 // namespace { |
815 | 1282 |
816 #if defined(UNIT_TEST) | 1283 #if defined(UNIT_TEST) |
817 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) | 1284 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) |
818 #elif defined(OS_WIN) | 1285 #elif defined(OS_WIN) |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
912 module_handle); | 1379 module_handle); |
913 return false; | 1380 return false; |
914 } | 1381 } |
915 | 1382 |
916 // Create a temporary GL context to query for multisampled pixel formats. | 1383 // Create a temporary GL context to query for multisampled pixel formats. |
917 HGLRC gl_context = ::wglCreateContext(intermediate_dc); | 1384 HGLRC gl_context = ::wglCreateContext(intermediate_dc); |
918 if (::wglMakeCurrent(intermediate_dc, gl_context)) { | 1385 if (::wglMakeCurrent(intermediate_dc, gl_context)) { |
919 // GL context was successfully created and applied to the window's DC. | 1386 // GL context was successfully created and applied to the window's DC. |
920 // Startup GLEW, the GL extensions wrangler. | 1387 // Startup GLEW, the GL extensions wrangler. |
921 if (InitGlew()) { | 1388 if (InitGlew()) { |
922 DLOG(INFO) << "Initialized GLEW " << ::glewGetString(GLEW_VERSION); | 1389 DLOG(INFO) << "Initialized GLEW " << glewGetString(GLEW_VERSION); |
923 } else { | 1390 } else { |
924 ::wglMakeCurrent(intermediate_dc, NULL); | 1391 ::wglMakeCurrent(intermediate_dc, NULL); |
925 ::wglDeleteContext(gl_context); | 1392 ::wglDeleteContext(gl_context); |
926 ::ReleaseDC(intermediate_window, intermediate_dc); | 1393 ::ReleaseDC(intermediate_window, intermediate_dc); |
927 ::DestroyWindow(intermediate_window); | 1394 ::DestroyWindow(intermediate_window); |
928 ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), | 1395 ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), |
929 module_handle); | 1396 module_handle); |
930 return false; | 1397 return false; |
931 } | 1398 } |
932 | 1399 |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1117 for (GLsizei ii = 0; ii < n; ++ii) { | 1584 for (GLsizei ii = 0; ii < n; ++ii) { |
1118 if (id_manager()->GetServiceId(client_ids[ii], &service_ids[ii])) { | 1585 if (id_manager()->GetServiceId(client_ids[ii], &service_ids[ii])) { |
1119 id_manager()->RemoveMapping(client_ids[ii], service_ids[ii]); | 1586 id_manager()->RemoveMapping(client_ids[ii], service_ids[ii]); |
1120 } else { | 1587 } else { |
1121 service_ids[ii] = 0; | 1588 service_ids[ii] = 0; |
1122 } | 1589 } |
1123 } | 1590 } |
1124 } | 1591 } |
1125 | 1592 |
1126 bool GLES2DecoderImpl::InitPlatformSpecific() { | 1593 bool GLES2DecoderImpl::InitPlatformSpecific() { |
| 1594 bool offscreen = pending_size_.width() > 0 && pending_size_.height() > 0; |
1127 #if defined(UNIT_TEST) | 1595 #if defined(UNIT_TEST) |
1128 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) | 1596 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) |
1129 #elif defined(OS_WIN) | 1597 #elif defined(OS_WIN) |
1130 // Do one-off initialization. | 1598 // Do one-off initialization. |
1131 static bool success = InitializeOneOff(anti_aliased_); | 1599 static bool success = InitializeOneOff(anti_aliased_); |
1132 if (!success) | 1600 if (!success) |
1133 return false; | 1601 return false; |
1134 | 1602 |
1135 if (hwnd()) { | 1603 if (offscreen) { |
1136 // The GL context will render to this window. | |
1137 gl_device_context_ = ::GetDC(hwnd()); | |
1138 | |
1139 if (!::SetPixelFormat(gl_device_context_, | |
1140 pixel_format_, | |
1141 &kPixelFormatDescriptor)) { | |
1142 DLOG(ERROR) << "Unable to set the pixel format for GL context."; | |
1143 DestroyPlatformSpecific(); | |
1144 return false; | |
1145 } | |
1146 } else { | |
1147 // Create a device context compatible with the primary display. | 1604 // Create a device context compatible with the primary display. |
1148 HDC display_device_context = ::CreateDC(L"DISPLAY", NULL, NULL, NULL); | 1605 HDC display_device_context = ::CreateDC(L"DISPLAY", NULL, NULL, NULL); |
1149 | 1606 |
1150 // Create a 1 x 1 pbuffer suitable for use with the device. | 1607 // Create a 1 x 1 pbuffer suitable for use with the device. This is just |
| 1608 // a stepping stone towards creating a frame buffer object. It doesn't |
| 1609 // matter what size it is. |
1151 const int kNoAttributes[] = { 0 }; | 1610 const int kNoAttributes[] = { 0 }; |
1152 pbuffer_ = ::wglCreatePbufferARB(display_device_context, | 1611 pbuffer_ = ::wglCreatePbufferARB(display_device_context, |
1153 pixel_format_, | 1612 pixel_format_, |
1154 1, 1, | 1613 1, 1, |
1155 kNoAttributes); | 1614 kNoAttributes); |
1156 ::DeleteDC(display_device_context); | 1615 ::DeleteDC(display_device_context); |
1157 if (!pbuffer_) { | 1616 if (!pbuffer_) { |
1158 DLOG(ERROR) << "Unable to create pbuffer."; | 1617 DLOG(ERROR) << "Unable to create pbuffer."; |
1159 DestroyPlatformSpecific(); | 1618 DestroyPlatformSpecific(); |
1160 return false; | 1619 return false; |
1161 } | 1620 } |
1162 | 1621 |
1163 gl_device_context_ = ::wglGetPbufferDCARB(pbuffer_); | 1622 gl_device_context_ = ::wglGetPbufferDCARB(pbuffer_); |
1164 if (!gl_device_context_) { | 1623 if (!gl_device_context_) { |
1165 DLOG(ERROR) << "Unable to get pbuffer device context."; | 1624 DLOG(ERROR) << "Unable to get pbuffer device context."; |
1166 DestroyPlatformSpecific(); | 1625 DestroyPlatformSpecific(); |
1167 return false; | 1626 return false; |
1168 } | 1627 } |
| 1628 } else { |
| 1629 // The GL context will render to this window. |
| 1630 gl_device_context_ = ::GetDC(hwnd()); |
| 1631 |
| 1632 if (!::SetPixelFormat(gl_device_context_, |
| 1633 pixel_format_, |
| 1634 &kPixelFormatDescriptor)) { |
| 1635 DLOG(ERROR) << "Unable to set the pixel format for GL context."; |
| 1636 DestroyPlatformSpecific(); |
| 1637 return false; |
| 1638 } |
1169 } | 1639 } |
1170 | 1640 |
1171 gl_context_ = ::wglCreateContext(gl_device_context_); | 1641 gl_context_ = ::wglCreateContext(gl_device_context_); |
1172 if (!gl_context_) { | 1642 if (!gl_context_) { |
1173 DLOG(ERROR) << "Failed to create GL context."; | 1643 DLOG(ERROR) << "Failed to create GL context."; |
1174 DestroyPlatformSpecific(); | 1644 DestroyPlatformSpecific(); |
1175 return false; | 1645 return false; |
1176 } | 1646 } |
| 1647 |
| 1648 if (parent_) { |
| 1649 if (!wglShareLists(parent_->gl_context_, gl_context_)) { |
| 1650 DLOG(ERROR) << "Could not share GL contexts."; |
| 1651 DestroyPlatformSpecific(); |
| 1652 return false; |
| 1653 } |
| 1654 } |
| 1655 |
1177 #elif defined(OS_LINUX) | 1656 #elif defined(OS_LINUX) |
| 1657 // TODO(apatrick): offscreen rendering not yet supported on this platform. |
| 1658 DCHECK(!offscreen); |
| 1659 |
| 1660 // TODO(apatrick): parent contexts not yet supported on this platform. |
| 1661 DCHECK(!parent_); |
| 1662 |
1178 DCHECK(window()); | 1663 DCHECK(window()); |
1179 if (!window()->Initialize()) | 1664 if (!window()->Initialize()) |
1180 return false; | 1665 return false; |
1181 #elif defined(OS_MACOSX) | 1666 #elif defined(OS_MACOSX) |
| 1667 // TODO(apatrick): offscreen rendering not yet supported on this platform. |
| 1668 DCHECK(!offscreen); |
| 1669 |
| 1670 // TODO(apatrick): parent contexts not yet supported on this platform. |
| 1671 DCHECK(!parent_); |
| 1672 |
1182 return surface_.Initialize(); | 1673 return surface_.Initialize(); |
1183 #endif | 1674 #endif |
1184 | 1675 |
1185 return true; | 1676 return true; |
1186 } | 1677 } |
1187 | 1678 |
1188 bool GLES2DecoderImpl::InitGlew() { | 1679 bool GLES2DecoderImpl::InitGlew() { |
1189 #if !defined(UNIT_TEST) && !defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) | 1680 #if !defined(UNIT_TEST) && !defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) |
1190 DLOG(INFO) << "Initializing GL and GLEW for GLES2Decoder."; | 1681 DLOG(INFO) << "Initializing GL and GLEW for GLES2Decoder."; |
1191 | 1682 |
1192 GLenum glew_error = glewInit(); | 1683 GLenum glew_error = glewInit(); |
1193 if (glew_error != GLEW_OK) { | 1684 if (glew_error != GLEW_OK) { |
1194 DLOG(ERROR) << "Unable to initialise GLEW : " | 1685 DLOG(ERROR) << "Unable to initialise GLEW : " |
1195 << ::glewGetErrorString(glew_error); | 1686 << glewGetErrorString(glew_error); |
1196 return false; | 1687 return false; |
1197 } | 1688 } |
1198 | 1689 |
1199 // Check to see that we can use the OpenGL vertex attribute APIs | 1690 // Check to see that we can use the OpenGL vertex attribute APIs |
1200 // TODO(petersont): Return false if this check fails, but because some | 1691 // TODO(petersont): Return false if this check fails, but because some |
1201 // Intel hardware does not support OpenGL 2.0, yet does support all of the | 1692 // Intel hardware does not support OpenGL 2.0, yet does support all of the |
1202 // extensions we require, we only log an error. A future CL should change | 1693 // extensions we require, we only log an error. A future CL should change |
1203 // this check to ensure that all of the extension strings we require are | 1694 // this check to ensure that all of the extension strings we require are |
1204 // present. | 1695 // present. |
1205 if (!GLEW_VERSION_2_0) { | 1696 if (!GLEW_VERSION_2_0) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1258 gl_device_context_ = NULL; | 1749 gl_device_context_ = NULL; |
1259 } | 1750 } |
1260 | 1751 |
1261 if (pbuffer_) { | 1752 if (pbuffer_) { |
1262 ::wglDestroyPbufferARB(pbuffer_); | 1753 ::wglDestroyPbufferARB(pbuffer_); |
1263 pbuffer_ = NULL; | 1754 pbuffer_ = NULL; |
1264 } | 1755 } |
1265 #endif | 1756 #endif |
1266 } | 1757 } |
1267 | 1758 |
| 1759 bool GLES2DecoderImpl::UpdateOffscreenFrameBufferSize() { |
| 1760 if (current_size_ != pending_size_) |
| 1761 return true; |
| 1762 |
| 1763 // Reallocate the offscreen target buffers. |
| 1764 if (!offscreen_target_color_texture_->AllocateStorage(pending_size_)) { |
| 1765 return false; |
| 1766 } |
| 1767 |
| 1768 if (!offscreen_target_depth_stencil_render_buffer_->AllocateStorage( |
| 1769 pending_size_, GL_DEPTH24_STENCIL8)) { |
| 1770 return false; |
| 1771 } |
| 1772 |
| 1773 // Attach the offscreen target buffers to the temporary frame buffer |
| 1774 // so they can be cleared using that frame buffer's clear parameters (all |
| 1775 // zero, no color mask, etc). |
| 1776 temporary_frame_buffer_->AttachRenderTexture( |
| 1777 offscreen_target_color_texture_.get()); |
| 1778 temporary_frame_buffer_->AttachDepthStencilRenderBuffer( |
| 1779 offscreen_target_depth_stencil_render_buffer_.get()); |
| 1780 if (temporary_frame_buffer_->CheckStatus() != |
| 1781 GL_FRAMEBUFFER_COMPLETE) { |
| 1782 return false; |
| 1783 } |
| 1784 |
| 1785 // Clear the offscreen target buffers to all zero (using the saved frame |
| 1786 // buffer they are temporarily attached to). |
| 1787 temporary_frame_buffer_->Clear( |
| 1788 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
| 1789 |
| 1790 // Detach the offscreen target buffer. |
| 1791 temporary_frame_buffer_->AttachRenderTexture(NULL); |
| 1792 temporary_frame_buffer_->AttachDepthStencilRenderBuffer(NULL); |
| 1793 |
| 1794 // Attach the offscreen target buffers to the proper frame buffer. |
| 1795 offscreen_target_frame_buffer_->AttachRenderTexture( |
| 1796 offscreen_target_color_texture_.get()); |
| 1797 offscreen_target_frame_buffer_->AttachDepthStencilRenderBuffer( |
| 1798 offscreen_target_depth_stencil_render_buffer_.get()); |
| 1799 if (offscreen_target_frame_buffer_->CheckStatus() != |
| 1800 GL_FRAMEBUFFER_COMPLETE) { |
| 1801 return false; |
| 1802 } |
| 1803 |
| 1804 // Create the saved offscreen color texture. |
| 1805 offscreen_saved_color_texture_->AllocateStorage(pending_size_); |
| 1806 |
| 1807 // Clear the offscreen saved color texture by copying the cleared target |
| 1808 // frame buffer into it. |
| 1809 { |
| 1810 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id()); |
| 1811 offscreen_saved_color_texture_->Copy(pending_size_); |
| 1812 } |
| 1813 |
| 1814 // Update the info about the offscreen saved color texture in the parent. |
| 1815 // The reference to the parent is a weak pointer and will become null if the |
| 1816 // parent is later destroyed. |
| 1817 if (parent_) { |
| 1818 GLuint service_id = offscreen_saved_color_texture_->id(); |
| 1819 |
| 1820 TextureManager::TextureInfo* info = |
| 1821 parent_->texture_manager()->GetTextureInfo(service_id); |
| 1822 DCHECK(info); |
| 1823 |
| 1824 info->SetLevelInfo(GL_TEXTURE_2D, |
| 1825 0, // level |
| 1826 GL_RGBA, |
| 1827 pending_size_.width(), pending_size_.height(), |
| 1828 1, // depth |
| 1829 0, // border |
| 1830 GL_RGBA, |
| 1831 GL_UNSIGNED_BYTE); |
| 1832 } |
| 1833 |
| 1834 current_size_ = pending_size_; |
| 1835 return true; |
| 1836 } |
| 1837 |
1268 #if defined(OS_MACOSX) | 1838 #if defined(OS_MACOSX) |
1269 | 1839 |
1270 uint64 GLES2DecoderImpl::SetWindowSizeForIOSurface(int32 width, int32 height) { | 1840 uint64 GLES2DecoderImpl::SetWindowSizeForIOSurface(int32 width, int32 height) { |
1271 #if defined(UNIT_TEST) | 1841 #if defined(UNIT_TEST) |
1272 return 0; | 1842 return 0; |
1273 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) | 1843 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) |
1274 return 0; | 1844 return 0; |
1275 #else | 1845 #else |
1276 return surface_.SetSurfaceSize(width, height); | 1846 return surface_.SetSurfaceSize(width, height); |
1277 #endif // !defined(UNIT_TEST) | 1847 #endif // !defined(UNIT_TEST) |
(...skipping 15 matching lines...) Expand all Loading... |
1293 Callback1<TransportDIB::Id>::Type* deallocator) { | 1863 Callback1<TransportDIB::Id>::Type* deallocator) { |
1294 surface_.SetTransportDIBAllocAndFree(allocator, deallocator); | 1864 surface_.SetTransportDIBAllocAndFree(allocator, deallocator); |
1295 } | 1865 } |
1296 #endif // defined(OS_MACOSX) | 1866 #endif // defined(OS_MACOSX) |
1297 | 1867 |
1298 void GLES2DecoderImpl::SetSwapBuffersCallback(Callback0::Type* callback) { | 1868 void GLES2DecoderImpl::SetSwapBuffersCallback(Callback0::Type* callback) { |
1299 swap_buffers_callback_.reset(callback); | 1869 swap_buffers_callback_.reset(callback); |
1300 } | 1870 } |
1301 | 1871 |
1302 void GLES2DecoderImpl::Destroy() { | 1872 void GLES2DecoderImpl::Destroy() { |
| 1873 MakeCurrent(); |
| 1874 |
| 1875 // Remove the saved frame buffer mapping from the parent decoder. The |
| 1876 // parent pointer is a weak pointer so it will be null if the parent has |
| 1877 // already been destroyed. |
| 1878 if (parent_) { |
| 1879 // First check the texture has been mapped into the parent. This might not |
| 1880 // be the case if initialization failed midway through. |
| 1881 GLuint service_id = offscreen_saved_color_texture_->id(); |
| 1882 GLuint client_id; |
| 1883 if (parent_->id_manager()->GetClientId(service_id, &client_id)) { |
| 1884 parent_->texture_manager()->RemoveTextureInfo(service_id); |
| 1885 parent_->id_manager()->RemoveMapping(client_id, service_id); |
| 1886 } |
| 1887 } |
| 1888 |
| 1889 if (offscreen_target_frame_buffer_.get()) |
| 1890 offscreen_target_frame_buffer_->Destroy(); |
| 1891 |
| 1892 if (offscreen_target_color_texture_.get()) |
| 1893 offscreen_target_color_texture_->Destroy(); |
| 1894 |
| 1895 if (offscreen_target_depth_stencil_render_buffer_.get()) |
| 1896 offscreen_target_depth_stencil_render_buffer_->Destroy(); |
| 1897 |
| 1898 if (temporary_frame_buffer_.get()) |
| 1899 temporary_frame_buffer_->Destroy(); |
| 1900 |
| 1901 if (offscreen_saved_color_texture_.get()) |
| 1902 offscreen_saved_color_texture_->Destroy(); |
| 1903 |
1303 #if defined(UNIT_TEST) | 1904 #if defined(UNIT_TEST) |
1304 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) | 1905 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) |
1305 #elif defined(OS_LINUX) | 1906 #elif defined(OS_LINUX) |
1306 DCHECK(window()); | 1907 DCHECK(window()); |
1307 window()->Destroy(); | 1908 window()->Destroy(); |
1308 #elif defined(OS_MACOSX) | 1909 #elif defined(OS_MACOSX) |
1309 surface_.Destroy(); | 1910 surface_.Destroy(); |
1310 #endif | 1911 #endif |
1311 | 1912 |
1312 DestroyPlatformSpecific(); | 1913 DestroyPlatformSpecific(); |
1313 } | 1914 } |
1314 | 1915 |
| 1916 void GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) { |
| 1917 // We can't resize the render buffers immediately because there might be a |
| 1918 // partial frame rendered into them and we don't want the tail end of that |
| 1919 // rendered into the reallocated storage. Defer until the next SwapBuffers. |
| 1920 pending_size_ = size; |
| 1921 } |
| 1922 |
1315 const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const { | 1923 const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const { |
1316 if (command_id > kStartPoint && command_id < kNumCommands) { | 1924 if (command_id > kStartPoint && command_id < kNumCommands) { |
1317 return gles2::GetCommandName(static_cast<CommandId>(command_id)); | 1925 return gles2::GetCommandName(static_cast<CommandId>(command_id)); |
1318 } | 1926 } |
1319 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id)); | 1927 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id)); |
1320 } | 1928 } |
1321 | 1929 |
1322 // Decode command with its arguments, and call the corresponding GL function. | 1930 // Decode command with its arguments, and call the corresponding GL function. |
1323 // Note: args is a pointer to the command buffer. As such, it could be changed | 1931 // Note: args is a pointer to the command buffer. As such, it could be changed |
1324 // by a (malicious) client at any time, so if validation has to happen, it | 1932 // by a (malicious) client at any time, so if validation has to happen, it |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1445 break; | 2053 break; |
1446 default: | 2054 default: |
1447 NOTREACHED(); // Validation should prevent us getting here. | 2055 NOTREACHED(); // Validation should prevent us getting here. |
1448 break; | 2056 break; |
1449 } | 2057 } |
1450 glBindBuffer(target, buffer); | 2058 glBindBuffer(target, buffer); |
1451 } | 2059 } |
1452 | 2060 |
1453 void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint framebuffer) { | 2061 void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint framebuffer) { |
1454 bound_framebuffer_ = framebuffer; | 2062 bound_framebuffer_ = framebuffer; |
| 2063 |
| 2064 // When rendering to an offscreen frame buffer, instead of unbinding from |
| 2065 // the current frame buffer, bind to the offscreen target frame buffer. |
| 2066 if (framebuffer == 0 && offscreen_target_frame_buffer_.get()) |
| 2067 framebuffer = offscreen_target_frame_buffer_->id(); |
| 2068 |
1455 glBindFramebufferEXT(target, framebuffer); | 2069 glBindFramebufferEXT(target, framebuffer); |
1456 } | 2070 } |
1457 | 2071 |
1458 void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint renderbuffer) { | 2072 void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint renderbuffer) { |
1459 bound_renderbuffer_ = renderbuffer; | 2073 bound_renderbuffer_ = renderbuffer; |
1460 glBindRenderbufferEXT(target, renderbuffer); | 2074 glBindRenderbufferEXT(target, renderbuffer); |
1461 } | 2075 } |
1462 | 2076 |
1463 void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint texture) { | 2077 void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint texture) { |
1464 TextureManager::TextureInfo* info = NULL; | 2078 TextureManager::TextureInfo* info = NULL; |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1678 glLinkProgram(program); | 2292 glLinkProgram(program); |
1679 GLenum error = glGetError(); | 2293 GLenum error = glGetError(); |
1680 if (error != GL_NO_ERROR) { | 2294 if (error != GL_NO_ERROR) { |
1681 RemoveProgramInfo(program); | 2295 RemoveProgramInfo(program); |
1682 SetGLError(error); | 2296 SetGLError(error); |
1683 } else { | 2297 } else { |
1684 info->Update(); | 2298 info->Update(); |
1685 } | 2299 } |
1686 }; | 2300 }; |
1687 | 2301 |
1688 void GLES2DecoderImpl::DoSwapBuffers() { | |
1689 #if defined(UNIT_TEST) | |
1690 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) | |
1691 #elif defined(OS_WIN) | |
1692 ::SwapBuffers(gl_device_context_); | |
1693 #elif defined(OS_LINUX) | |
1694 DCHECK(window()); | |
1695 window()->SwapBuffers(); | |
1696 #elif defined(OS_MACOSX) | |
1697 // TODO(kbr): Need to property hook up and track the OpenGL state and hook | |
1698 // up the notion of the currently bound FBO. | |
1699 surface_.SwapBuffers(); | |
1700 #endif | |
1701 if (swap_buffers_callback_.get()) { | |
1702 swap_buffers_callback_->Run(); | |
1703 } | |
1704 } | |
1705 | |
1706 void GLES2DecoderImpl::DoTexParameterf( | 2302 void GLES2DecoderImpl::DoTexParameterf( |
1707 GLenum target, GLenum pname, GLfloat param) { | 2303 GLenum target, GLenum pname, GLfloat param) { |
1708 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | 2304 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
1709 if (!info) { | 2305 if (!info) { |
1710 SetGLError(GL_INVALID_VALUE); | 2306 SetGLError(GL_INVALID_VALUE); |
1711 } else { | 2307 } else { |
1712 info->SetParameter(pname, static_cast<GLint>(param)); | 2308 info->SetParameter(pname, static_cast<GLint>(param)); |
1713 glTexParameterf(target, pname, param); | 2309 glTexParameterf(target, pname, param); |
1714 } | 2310 } |
1715 } | 2311 } |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1805 error_bits_ |= GLES2Util::GLErrorToErrorBit(error); | 2401 error_bits_ |= GLES2Util::GLErrorToErrorBit(error); |
1806 } | 2402 } |
1807 | 2403 |
1808 void GLES2DecoderImpl::CopyRealGLErrorsToWrapper() { | 2404 void GLES2DecoderImpl::CopyRealGLErrorsToWrapper() { |
1809 GLenum error; | 2405 GLenum error; |
1810 while ((error = glGetError()) != GL_NO_ERROR) { | 2406 while ((error = glGetError()) != GL_NO_ERROR) { |
1811 SetGLError(error); | 2407 SetGLError(error); |
1812 } | 2408 } |
1813 } | 2409 } |
1814 | 2410 |
| 2411 void GLES2DecoderImpl::ClearRealGLErrors() { |
| 2412 GLenum error; |
| 2413 while ((error = glGetError()) != GL_NO_ERROR) { |
| 2414 NOTREACHED() << "GL error " << error << " was unhandled."; |
| 2415 } |
| 2416 } |
| 2417 |
1815 bool GLES2DecoderImpl::VertexAttribInfo::CanAccess(GLuint index) { | 2418 bool GLES2DecoderImpl::VertexAttribInfo::CanAccess(GLuint index) { |
1816 if (!enabled_) { | 2419 if (!enabled_) { |
1817 return true; | 2420 return true; |
1818 } | 2421 } |
1819 | 2422 |
1820 if (!buffer_ || buffer_->IsDeleted()) { | 2423 if (!buffer_ || buffer_->IsDeleted()) { |
1821 return false; | 2424 return false; |
1822 } | 2425 } |
1823 | 2426 |
1824 // The number of elements that can be accessed. | 2427 // The number of elements that can be accessed. |
(...skipping 1149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2974 return error::kNoError; | 3577 return error::kNoError; |
2975 } | 3578 } |
2976 result->success = 1; // true. | 3579 result->success = 1; // true. |
2977 result->size = attrib_info->size; | 3580 result->size = attrib_info->size; |
2978 result->type = attrib_info->type; | 3581 result->type = attrib_info->type; |
2979 Bucket* bucket = CreateBucket(name_bucket_id); | 3582 Bucket* bucket = CreateBucket(name_bucket_id); |
2980 bucket->SetFromString(attrib_info->name); | 3583 bucket->SetFromString(attrib_info->name); |
2981 return error::kNoError; | 3584 return error::kNoError; |
2982 } | 3585 } |
2983 | 3586 |
| 3587 error::Error GLES2DecoderImpl::HandleSwapBuffers( |
| 3588 uint32 immediate_data_size, const gles2::SwapBuffers& c) { |
| 3589 // Check a client created frame buffer is not bound. TODO(apatrick): |
| 3590 // this error is overkill. It will require that the client recreate the |
| 3591 // context to continue. |
| 3592 if (bound_framebuffer_ != 0) |
| 3593 return error::kLostContext; |
| 3594 |
| 3595 // If offscreen then don't actually SwapBuffers to the display. Just copy |
| 3596 // the rendered frame to another frame buffer. |
| 3597 if (offscreen_target_frame_buffer_.get()) { |
| 3598 ScopedGLErrorSuppressor suppressor(this); |
| 3599 |
| 3600 // First check to see if a deferred offscreen render buffer resize is |
| 3601 // pending. |
| 3602 if (!UpdateOffscreenFrameBufferSize()) |
| 3603 return error::kLostContext; |
| 3604 |
| 3605 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id()); |
| 3606 offscreen_saved_color_texture_->Copy(current_size_); |
| 3607 } else { |
| 3608 #if defined(UNIT_TEST) |
| 3609 #elif defined(GLES2_GPU_SERVICE_BACKEND_NATIVE_GLES2) |
| 3610 #elif defined(OS_WIN) |
| 3611 ::SwapBuffers(gl_device_context_); |
| 3612 #elif defined(OS_LINUX) |
| 3613 DCHECK(window()); |
| 3614 window()->SwapBuffers(); |
| 3615 #elif defined(OS_MACOSX) |
| 3616 // TODO(kbr): Need to property hook up and track the OpenGL state and hook |
| 3617 // up the notion of the currently bound FBO. |
| 3618 surface_.SwapBuffers(); |
| 3619 #endif |
| 3620 } |
| 3621 |
| 3622 if (swap_buffers_callback_.get()) { |
| 3623 swap_buffers_callback_->Run(); |
| 3624 } |
| 3625 |
| 3626 return error::kNoError; |
| 3627 } |
| 3628 |
2984 // Include the auto-generated part of this file. We split this because it means | 3629 // Include the auto-generated part of this file. We split this because it means |
2985 // we can easily edit the non-auto generated parts right here in this file | 3630 // we can easily edit the non-auto generated parts right here in this file |
2986 // instead of having to edit some template or the code generator. | 3631 // instead of having to edit some template or the code generator. |
2987 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 3632 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
2988 | 3633 |
2989 } // namespace gles2 | 3634 } // namespace gles2 |
2990 } // namespace gpu | 3635 } // namespace gpu |
OLD | NEW |