gles2_cmd_decoder.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 2012 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 "gpu/command_buffer/service/gles2_cmd_decoder.h" 6 7#include <stdio.h> 8 9#include <algorithm> 10#include <list> 11#include <map> 12#include <string> 13#include <vector> 14 15#include "base/at_exit.h" 16#include "base/atomicops.h" 17#include "base/bind.h" 18#include "base/command_line.h" 19#include "base/debug/trace_event.h" 20#if defined(OS_MACOSX) 21#include "base/mac/scoped_cftyperef.h" 22#endif 23#include "base/memory/scoped_ptr.h" 24#include "base/memory/weak_ptr.h" 25#include "base/string_number_conversions.h" 26#include "build/build_config.h" 27#define GLES2_GPU_SERVICE 1 28#include "gpu/command_buffer/common/gles2_cmd_format.h" 29#include "gpu/command_buffer/common/gles2_cmd_utils.h" 30#include "gpu/command_buffer/common/debug_marker_manager.h" 31#include "gpu/command_buffer/common/id_allocator.h" 32#include "gpu/command_buffer/service/buffer_manager.h" 33#include "gpu/command_buffer/service/cmd_buffer_engine.h" 34#include "gpu/command_buffer/service/context_group.h" 35#include "gpu/command_buffer/service/context_state.h" 36#include "gpu/command_buffer/service/feature_info.h" 37#include "gpu/command_buffer/service/framebuffer_manager.h" 38#include "gpu/command_buffer/service/gl_utils.h" 39#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" 40#include "gpu/command_buffer/service/gles2_cmd_validation.h" 41#include "gpu/command_buffer/service/gpu_switches.h" 42#include "gpu/command_buffer/service/image_manager.h" 43#include "gpu/command_buffer/service/mailbox_manager.h" 44#include "gpu/command_buffer/service/memory_tracking.h" 45#include "gpu/command_buffer/service/program_manager.h" 46#include "gpu/command_buffer/service/query_manager.h" 47#include "gpu/command_buffer/service/renderbuffer_manager.h" 48#include "gpu/command_buffer/service/shader_manager.h" 49#include "gpu/command_buffer/service/shader_translator.h" 50#include "gpu/command_buffer/service/shader_translator_cache.h" 51#include "gpu/command_buffer/service/stream_texture.h" 52#include "gpu/command_buffer/service/stream_texture_manager.h" 53#include "gpu/command_buffer/service/texture_definition.h" 54#include "gpu/command_buffer/service/texture_manager.h" 55#include "gpu/command_buffer/service/vertex_attrib_manager.h" 56#include "gpu/command_buffer/service/vertex_array_manager.h" 57#include "ui/gl/gl_context.h" 58#include "ui/gl/gl_image.h" 59#include "ui/gl/gl_implementation.h" 60#include "ui/gl/gl_surface.h" 61#if defined(OS_MACOSX) 62#include "ui/surface/io_surface_support_mac.h" 63#endif 64 65#if !defined(GL_DEPTH24_STENCIL8) 66#define GL_DEPTH24_STENCIL8 0x88F0 67#endif 68 69namespace gpu { 70namespace gles2 { 71 72namespace { 73static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives"; 74} 75 76class GLES2DecoderImpl; 77 78// Check that certain assumptions the code makes are true. There are places in 79// the code where shared memory is passed direclty to GL. Example, glUniformiv, 80// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe 81// a few others) are 32bits. If they are not 32bits the code will have to change 82// to call those GL functions with service side memory and then copy the results 83// to shared memory, converting the sizes. 84COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT 85 GLint_not_same_size_as_uint32); 86COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT 87 GLint_not_same_size_as_uint32); 88COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT 89 GLfloat_not_same_size_as_float); 90 91// TODO(kbr): the use of this anonymous namespace core dumps the 92// linker on Mac OS X 10.6 when the symbol ordering file is used 93// namespace { 94 95// Returns the address of the first byte after a struct. 96template <typename T> 97const void* AddressAfterStruct(const T& pod) { 98 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod); 99} 100 101// Returns the address of the frst byte after the struct or NULL if size > 102// immediate_data_size. 103template <typename RETURN_TYPE, typename COMMAND_TYPE> 104RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod, 105 uint32 size, 106 uint32 immediate_data_size) { 107 return (size <= immediate_data_size) ? 108 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) : 109 NULL; 110} 111 112// Computes the data size for certain gl commands like glUniform. 113bool ComputeDataSize( 114 GLuint count, 115 size_t size, 116 unsigned int elements_per_unit, 117 uint32* dst) { 118 uint32 value; 119 if (!SafeMultiplyUint32(count, size, &value)) { 120 return false; 121 } 122 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) { 123 return false; 124 } 125 *dst = value; 126 return true; 127} 128 129// A struct to hold info about each command. 130struct CommandInfo { 131 int arg_flags; // How to handle the arguments for this command 132 int arg_count; // How many arguments are expected for this command. 133}; 134 135// A table of CommandInfo for all the commands. 136const CommandInfo g_command_info[] = { 137 #define GLES2_CMD_OP(name) { \ 138 name::kArgFlags, \ 139 sizeof(name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \ 140 141 GLES2_COMMAND_LIST(GLES2_CMD_OP) 142 143 #undef GLES2_CMD_OP 144}; 145 146// Return true if a character belongs to the ASCII subset as defined in 147// GLSL ES 1.0 spec section 3.1. 148static bool CharacterIsValidForGLES(unsigned char c) { 149 // Printing characters are valid except " $ ` @ \ ' DEL. 150 if (c >= 32 && c <= 126 && 151 c != '"' && 152 c != '$' && 153 c != '`' && 154 c != '@' && 155 c != '\\' && 156 c != '\'') { 157 return true; 158 } 159 // Horizontal tab, line feed, vertical tab, form feed, carriage return 160 // are also valid. 161 if (c >= 9 && c <= 13) { 162 return true; 163 } 164 165 return false; 166} 167 168static bool StringIsValidForGLES(const char* str) { 169 for (; *str; ++str) { 170 if (!CharacterIsValidForGLES(*str)) { 171 return false; 172 } 173 } 174 return true; 175} 176 177static inline GLenum GetTexInternalFormat(GLenum internal_format) { 178 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 179 if (internal_format == GL_BGRA_EXT || internal_format == GL_BGRA8_EXT) 180 return GL_RGBA8; 181 } 182 return internal_format; 183} 184 185static void WrappedTexImage2D( 186 GLenum target, 187 GLint level, 188 GLenum internal_format, 189 GLsizei width, 190 GLsizei height, 191 GLint border, 192 GLenum format, 193 GLenum type, 194 const void* pixels) { 195 GLenum gl_internal_format = GetTexInternalFormat(internal_format); 196 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 197 if (type == GL_FLOAT) { 198 switch (format) { 199 case GL_RGBA: 200 gl_internal_format = GL_RGBA32F_ARB; 201 break; 202 case GL_RGB: 203 gl_internal_format = GL_RGB32F_ARB; 204 break; 205 case GL_LUMINANCE_ALPHA: 206 gl_internal_format = GL_LUMINANCE_ALPHA32F_ARB; 207 break; 208 case GL_LUMINANCE: 209 gl_internal_format = GL_LUMINANCE32F_ARB; 210 break; 211 case GL_ALPHA: 212 gl_internal_format = GL_ALPHA32F_ARB; 213 break; 214 default: 215 NOTREACHED(); 216 break; 217 } 218 } else if (type == GL_HALF_FLOAT_OES) { 219 switch (format) { 220 case GL_RGBA: 221 gl_internal_format = GL_RGBA16F_ARB; 222 break; 223 case GL_RGB: 224 gl_internal_format = GL_RGB16F_ARB; 225 break; 226 case GL_LUMINANCE_ALPHA: 227 gl_internal_format = GL_LUMINANCE_ALPHA16F_ARB; 228 break; 229 case GL_LUMINANCE: 230 gl_internal_format = GL_LUMINANCE16F_ARB; 231 break; 232 case GL_ALPHA: 233 gl_internal_format = GL_ALPHA16F_ARB; 234 break; 235 default: 236 NOTREACHED(); 237 break; 238 } 239 } 240 } 241 glTexImage2D( 242 target, level, gl_internal_format, width, height, border, format, type, 243 pixels); 244} 245 246// Wrapper for glEnable/glDisable that doesn't suck. 247static void EnableDisable(GLenum pname, bool enable) { 248 if (enable) { 249 glEnable(pname); 250 } else { 251 glDisable(pname); 252 } 253} 254 255// This class prevents any GL errors that occur when it is in scope from 256// being reported to the client. 257class ScopedGLErrorSuppressor { 258 public: 259 explicit ScopedGLErrorSuppressor(GLES2DecoderImpl* decoder); 260 ~ScopedGLErrorSuppressor(); 261 private: 262 GLES2DecoderImpl* decoder_; 263 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor); 264}; 265 266// Temporarily changes a decoder's bound 2D texture and restore it when this 267// object goes out of scope. Also temporarily switches to using active texture 268// unit zero in case the client has changed that to something invalid. 269class ScopedTexture2DBinder { 270 public: 271 ScopedTexture2DBinder(GLES2DecoderImpl* decoder, GLuint id); 272 ~ScopedTexture2DBinder(); 273 274 private: 275 GLES2DecoderImpl* decoder_; 276 DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder); 277}; 278 279// Temporarily changes a decoder's bound render buffer and restore it when this 280// object goes out of scope. 281class ScopedRenderBufferBinder { 282 public: 283 ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, GLuint id); 284 ~ScopedRenderBufferBinder(); 285 286 private: 287 GLES2DecoderImpl* decoder_; 288 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder); 289}; 290 291// Temporarily changes a decoder's bound frame buffer and restore it when this 292// object goes out of scope. 293class ScopedFrameBufferBinder { 294 public: 295 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id); 296 ~ScopedFrameBufferBinder(); 297 298 private: 299 GLES2DecoderImpl* decoder_; 300 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder); 301}; 302 303// Temporarily changes a decoder's bound frame buffer to a resolved version of 304// the multisampled offscreen render buffer if that buffer is multisampled, and, 305// if it is bound or enforce_internal_framebuffer is true. If internal is 306// true, the resolved framebuffer is not visible to the parent. 307class ScopedResolvedFrameBufferBinder { 308 public: 309 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder, 310 bool enforce_internal_framebuffer, 311 bool internal); 312 ~ScopedResolvedFrameBufferBinder(); 313 314 private: 315 GLES2DecoderImpl* decoder_; 316 bool resolve_and_bind_; 317 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder); 318}; 319 320// This class records texture upload time when in scope. 321class ScopedTextureUploadTimer { 322 public: 323 explicit ScopedTextureUploadTimer(GLES2DecoderImpl* decoder); 324 ~ScopedTextureUploadTimer(); 325 326 private: 327 GLES2DecoderImpl* decoder_; 328 base::TimeTicks begin_time_; 329 DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer); 330}; 331 332// Encapsulates an OpenGL texture. 333class Texture { 334 public: 335 explicit Texture(GLES2DecoderImpl* decoder); 336 ~Texture(); 337 338 // Create a new render texture. 339 void Create(); 340 341 // Set the initial size and format of a render texture or resize it. 342 bool AllocateStorage(const gfx::Size& size, GLenum format); 343 344 // Copy the contents of the currently bound frame buffer. 345 void Copy(const gfx::Size& size, GLenum format); 346 347 // Destroy the render texture. This must be explicitly called before 348 // destroying this object. 349 void Destroy(); 350 351 // Invalidate the texture. This can be used when a context is lost and it is 352 // not possible to make it current in order to free the resource. 353 void Invalidate(); 354 355 GLuint id() const { 356 return id_; 357 } 358 359 gfx::Size size() const { 360 return size_; 361 } 362 363 size_t estimated_size() const { 364 return memory_tracker_.GetMemRepresented(); 365 } 366 367 private: 368 GLES2DecoderImpl* decoder_; 369 MemoryTypeTracker memory_tracker_; 370 GLuint id_; 371 gfx::Size size_; 372 DISALLOW_COPY_AND_ASSIGN(Texture); 373}; 374 375// Encapsulates an OpenGL render buffer of any format. 376class RenderBuffer { 377 public: 378 explicit RenderBuffer(GLES2DecoderImpl* decoder); 379 ~RenderBuffer(); 380 381 // Create a new render buffer. 382 void Create(); 383 384 // Set the initial size and format of a render buffer or resize it. 385 bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples); 386 387 // Destroy the render buffer. This must be explicitly called before destroying 388 // this object. 389 void Destroy(); 390 391 // Invalidate the render buffer. This can be used when a context is lost and 392 // it is not possible to make it current in order to free the resource. 393 void Invalidate(); 394 395 GLuint id() const { 396 return id_; 397 } 398 399 size_t estimated_size() const { 400 return memory_tracker_.GetMemRepresented(); 401 } 402 403 private: 404 GLES2DecoderImpl* decoder_; 405 MemoryTypeTracker memory_tracker_; 406 GLuint id_; 407 DISALLOW_COPY_AND_ASSIGN(RenderBuffer); 408}; 409 410// Encapsulates an OpenGL frame buffer. 411class FrameBuffer { 412 public: 413 explicit FrameBuffer(GLES2DecoderImpl* decoder); 414 ~FrameBuffer(); 415 416 // Create a new frame buffer. 417 void Create(); 418 419 // Attach a color render buffer to a frame buffer. 420 void AttachRenderTexture(Texture* texture); 421 422 // Attach a render buffer to a frame buffer. Note that this unbinds any 423 // currently bound frame buffer. 424 void AttachRenderBuffer(GLenum target, RenderBuffer* render_buffer); 425 426 // Destroy the frame buffer. This must be explicitly called before destroying 427 // this object. 428 void Destroy(); 429 430 // Invalidate the frame buffer. This can be used when a context is lost and it 431 // is not possible to make it current in order to free the resource. 432 void Invalidate(); 433 434 // See glCheckFramebufferStatusEXT. 435 GLenum CheckStatus(); 436 437 GLuint id() const { 438 return id_; 439 } 440 441 private: 442 GLES2DecoderImpl* decoder_; 443 GLuint id_; 444 DISALLOW_COPY_AND_ASSIGN(FrameBuffer); 445}; 446 447// } // anonymous namespace. 448 449bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id, 450 uint32* service_texture_id) { 451 return false; 452} 453 454GLES2Decoder::GLES2Decoder() 455 : debug_(false), 456 log_commands_(false), 457 log_synthesized_gl_errors_(true) { 458} 459 460GLES2Decoder::~GLES2Decoder() { 461} 462 463bool GLES2Decoder::testing_force_is_angle_; 464 465void GLES2Decoder::set_testing_force_is_angle(bool force) { 466 testing_force_is_angle_ = force; 467} 468 469bool GLES2Decoder::IsAngle() { 470#if defined(OS_WIN) 471 return testing_force_is_angle_ || 472 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; 473#else 474 return testing_force_is_angle_; 475#endif 476} 477 478// This class implements GLES2Decoder so we don't have to expose all the GLES2 479// cmd stuff to outside this class. 480class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, 481 public GLES2Decoder { 482 public: 483 static const int kMaxLogMessages = 256; 484 485 explicit GLES2DecoderImpl(ContextGroup* group); 486 virtual ~GLES2DecoderImpl(); 487 488 // Overridden from AsyncAPIInterface. 489 virtual Error DoCommand(unsigned int command, 490 unsigned int arg_count, 491 const void* args) OVERRIDE; 492 493 // Overridden from AsyncAPIInterface. 494 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE; 495 496 // Overridden from GLES2Decoder. 497 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface, 498 const scoped_refptr<gfx::GLContext>& context, 499 bool offscreen, 500 const gfx::Size& size, 501 const DisallowedFeatures& disallowed_features, 502 const char* allowed_extensions, 503 const std::vector<int32>& attribs) OVERRIDE; 504 virtual void Destroy(bool have_context) OVERRIDE; 505 virtual void SetSurface( 506 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE; 507 virtual bool SetParent(GLES2Decoder* parent_decoder, 508 uint32 parent_texture_id) OVERRIDE; 509 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE; 510 void UpdateParentTextureInfo(); 511 virtual bool MakeCurrent() OVERRIDE; 512 virtual void ReleaseCurrent() OVERRIDE; 513 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; } 514 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); } 515 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); } 516 virtual void RestoreState() const OVERRIDE; 517 virtual QueryManager* GetQueryManager() OVERRIDE { 518 return query_manager_.get(); 519 } 520 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE { 521 return vertex_array_manager_.get(); 522 } 523 virtual bool ProcessPendingQueries() OVERRIDE; 524 525 virtual void SetGLError(GLenum error, 526 const char* function_name, 527 const char* msg); 528 virtual void SetGLErrorInvalidEnum(const char* function_name, 529 GLenum value, 530 const char* label); 531 virtual void SetResizeCallback( 532 const base::Callback<void(gfx::Size)>& callback) OVERRIDE; 533 534 virtual void SetMsgCallback(const MsgCallback& callback) OVERRIDE; 535 536 virtual void SetStreamTextureManager(StreamTextureManager* manager) OVERRIDE; 537 virtual bool GetServiceTextureId(uint32 client_texture_id, 538 uint32* service_texture_id) OVERRIDE; 539 540 virtual uint32 GetGLError() OVERRIDE; 541 542 virtual uint32 GetTextureUploadCount() OVERRIDE; 543 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE; 544 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE; 545 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE; 546 547 // Restores the current state to the user's settings. 548 void RestoreCurrentFramebufferBindings(); 549 void RestoreCurrentRenderbufferBindings(); 550 void RestoreCurrentTexture2DBindings(); 551 552 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer. 553 void ApplyDirtyState(); 554 555 // Reapply the texture parameters to the given texture. 556 void BindAndApplyTextureParameters(TextureManager::TextureInfo* info); 557 558 // These check the state of the currently bound framebuffer or the 559 // backbuffer if no framebuffer is bound. 560 bool BoundFramebufferHasColorAttachmentWithAlpha(); 561 bool BoundFramebufferHasDepthAttachment(); 562 bool BoundFramebufferHasStencilAttachment(); 563 564 virtual error::ContextLostReason GetContextLostReason() OVERRIDE; 565 566 private: 567 friend class ScopedGLErrorSuppressor; 568 friend class ScopedResolvedFrameBufferBinder; 569 friend class ScopedTextureUploadTimer; 570 friend class Texture; 571 friend class RenderBuffer; 572 friend class FrameBuffer; 573 574 // Initialize or re-initialize the shader translator. 575 bool InitializeShaderTranslator(); 576 577 void UpdateCapabilities(); 578 579 // Helpers for the glGen and glDelete functions. 580 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids); 581 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids); 582 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids); 583 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids); 584 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids); 585 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids); 586 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids); 587 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids); 588 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids); 589 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids); 590 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); 591 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids); 592 593 // TODO(gman): Cache these pointers? 594 BufferManager* buffer_manager() { 595 return group_->buffer_manager(); 596 } 597 598 RenderbufferManager* renderbuffer_manager() { 599 return group_->renderbuffer_manager(); 600 } 601 602 FramebufferManager* framebuffer_manager() { 603 return group_->framebuffer_manager(); 604 } 605 606 ProgramManager* program_manager() { 607 return group_->program_manager(); 608 } 609 610 ShaderManager* shader_manager() { 611 return group_->shader_manager(); 612 } 613 614 TextureManager* texture_manager() { 615 return group_->texture_manager(); 616 } 617 618 MailboxManager* mailbox_manager() { 619 return group_->mailbox_manager(); 620 } 621 622 ImageManager* image_manager() { 623 return group_->image_manager(); 624 } 625 626 VertexArrayManager* vertex_array_manager() { 627 return vertex_array_manager_.get(); 628 } 629 630 bool IsOffscreenBufferMultisampled() const { 631 return offscreen_target_samples_ > 1; 632 } 633 634 // Creates a TextureInfo for the given texture. 635 TextureManager::TextureInfo* CreateTextureInfo( 636 GLuint client_id, GLuint service_id) { 637 return texture_manager()->CreateTextureInfo(client_id, service_id); 638 } 639 640 // Gets the texture info for the given texture. Returns NULL if none exists. 641 TextureManager::TextureInfo* GetTextureInfo(GLuint client_id) { 642 TextureManager::TextureInfo* info = 643 texture_manager()->GetTextureInfo(client_id); 644 return info; 645 } 646 647 // Deletes the texture info for the given texture. 648 void RemoveTextureInfo(GLuint client_id) { 649 texture_manager()->RemoveTextureInfo(client_id); 650 } 651 652 // Get the size (in pixels) of the currently bound frame buffer (either FBO 653 // or regular back buffer). 654 gfx::Size GetBoundReadFrameBufferSize(); 655 656 // Get the format of the currently bound frame buffer (either FBO or regular 657 // back buffer) 658 GLenum GetBoundReadFrameBufferInternalFormat(); 659 GLenum GetBoundDrawFrameBufferInternalFormat(); 660 661 // Wrapper for CompressedTexImage2D commands. 662 error::Error DoCompressedTexImage2D( 663 GLenum target, 664 GLint level, 665 GLenum internal_format, 666 GLsizei width, 667 GLsizei height, 668 GLint border, 669 GLsizei image_size, 670 const void* data); 671 672 // Wrapper for CompressedTexSubImage2D. 673 void DoCompressedTexSubImage2D( 674 GLenum target, 675 GLint level, 676 GLint xoffset, 677 GLint yoffset, 678 GLsizei width, 679 GLsizei height, 680 GLenum format, 681 GLsizei imageSize, 682 const void * data); 683 684 // Wrapper for CopyTexImage2D. 685 void DoCopyTexImage2D( 686 GLenum target, 687 GLint level, 688 GLenum internal_format, 689 GLint x, 690 GLint y, 691 GLsizei width, 692 GLsizei height, 693 GLint border); 694 695 // Wrapper for CopyTexSubImage2D. 696 void DoCopyTexSubImage2D( 697 GLenum target, 698 GLint level, 699 GLint xoffset, 700 GLint yoffset, 701 GLint x, 702 GLint y, 703 GLsizei width, 704 GLsizei height); 705 706 // Wrapper for TexImage2D commands. 707 error::Error DoTexImage2D( 708 GLenum target, 709 GLint level, 710 GLenum internal_format, 711 GLsizei width, 712 GLsizei height, 713 GLint border, 714 GLenum format, 715 GLenum type, 716 const void* pixels, 717 uint32 pixels_size); 718 719 // Wrapper for TexSubImage2D. 720 void DoTexSubImage2D( 721 GLenum target, 722 GLint level, 723 GLint xoffset, 724 GLint yoffset, 725 GLsizei width, 726 GLsizei height, 727 GLenum format, 728 GLenum type, 729 const void * data); 730 731 // Wrapper for TexImageIOSurface2DCHROMIUM. 732 void DoTexImageIOSurface2DCHROMIUM( 733 GLenum target, 734 GLsizei width, 735 GLsizei height, 736 GLuint io_surface_id, 737 GLuint plane); 738 739 void DoCopyTextureCHROMIUM( 740 GLenum target, 741 GLuint source_id, 742 GLuint target_id, 743 GLint level, 744 GLenum internal_format); 745 746 // Wrapper for TexStorage2DEXT. 747 void DoTexStorage2DEXT( 748 GLenum target, 749 GLint levels, 750 GLenum internal_format, 751 GLsizei width, 752 GLsizei height); 753 754 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key); 755 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key); 756 757 void DoBindTexImage2DCHROMIUM( 758 GLenum target, 759 GLint image_id); 760 void DoReleaseTexImage2DCHROMIUM( 761 GLenum target, 762 GLint image_id); 763 764 // Creates a ProgramInfo for the given program. 765 ProgramManager::ProgramInfo* CreateProgramInfo( 766 GLuint client_id, GLuint service_id) { 767 return program_manager()->CreateProgramInfo(client_id, service_id); 768 } 769 770 // Gets the program info for the given program. Returns NULL if none exists. 771 ProgramManager::ProgramInfo* GetProgramInfo(GLuint client_id) { 772 return program_manager()->GetProgramInfo(client_id); 773 } 774 775 // Gets the program info for the given program. If it's not a program 776 // generates a GL error. Returns NULL if not program. 777 ProgramManager::ProgramInfo* GetProgramInfoNotShader( 778 GLuint client_id, const char* function_name) { 779 ProgramManager::ProgramInfo* info = GetProgramInfo(client_id); 780 if (!info) { 781 if (GetShaderInfo(client_id)) { 782 SetGLError( 783 GL_INVALID_OPERATION, function_name, "shader passed for program"); 784 } else { 785 SetGLError(GL_INVALID_VALUE, function_name, "unknown program"); 786 } 787 } 788 return info; 789 } 790 791 792 // Creates a ShaderInfo for the given shader. 793 ShaderManager::ShaderInfo* CreateShaderInfo( 794 GLuint client_id, 795 GLuint service_id, 796 GLenum shader_type) { 797 return shader_manager()->CreateShaderInfo( 798 client_id, service_id, shader_type); 799 } 800 801 // Gets the shader info for the given shader. Returns NULL if none exists. 802 ShaderManager::ShaderInfo* GetShaderInfo(GLuint client_id) { 803 return shader_manager()->GetShaderInfo(client_id); 804 } 805 806 // Gets the shader info for the given shader. If it's not a shader generates a 807 // GL error. Returns NULL if not shader. 808 ShaderManager::ShaderInfo* GetShaderInfoNotProgram( 809 GLuint client_id, const char* function_name) { 810 ShaderManager::ShaderInfo* info = GetShaderInfo(client_id); 811 if (!info) { 812 if (GetProgramInfo(client_id)) { 813 SetGLError( 814 GL_INVALID_OPERATION, function_name, "program passed for shader"); 815 } else { 816 SetGLError( 817 GL_INVALID_VALUE, function_name, "unknown shader"); 818 } 819 } 820 return info; 821 } 822 823 // Creates a buffer info for the given buffer. 824 void CreateBufferInfo(GLuint client_id, GLuint service_id) { 825 return buffer_manager()->CreateBufferInfo(client_id, service_id); 826 } 827 828 // Gets the buffer info for the given buffer. 829 BufferManager::BufferInfo* GetBufferInfo(GLuint client_id) { 830 BufferManager::BufferInfo* info = 831 buffer_manager()->GetBufferInfo(client_id); 832 return info; 833 } 834 835 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used 836 // on glDeleteBuffers so we can make sure the user does not try to render 837 // with deleted buffers. 838 void RemoveBufferInfo(GLuint client_id); 839 840 // Creates a framebuffer info for the given framebuffer. 841 void CreateFramebufferInfo(GLuint client_id, GLuint service_id) { 842 return framebuffer_manager()->CreateFramebufferInfo(client_id, service_id); 843 } 844 845 // Gets the framebuffer info for the given framebuffer. 846 FramebufferManager::FramebufferInfo* GetFramebufferInfo( 847 GLuint client_id) { 848 FramebufferManager::FramebufferInfo* info = 849 framebuffer_manager()->GetFramebufferInfo(client_id); 850 return info; 851 } 852 853 // Removes the framebuffer info for the given framebuffer. 854 void RemoveFramebufferInfo(GLuint client_id) { 855 framebuffer_manager()->RemoveFramebufferInfo(client_id); 856 } 857 858 // Creates a renderbuffer info for the given renderbuffer. 859 void CreateRenderbufferInfo(GLuint client_id, GLuint service_id) { 860 return renderbuffer_manager()->CreateRenderbufferInfo( 861 client_id, service_id); 862 } 863 864 // Gets the renderbuffer info for the given renderbuffer. 865 RenderbufferManager::RenderbufferInfo* GetRenderbufferInfo( 866 GLuint client_id) { 867 RenderbufferManager::RenderbufferInfo* info = 868 renderbuffer_manager()->GetRenderbufferInfo(client_id); 869 return info; 870 } 871 872 // Removes the renderbuffer info for the given renderbuffer. 873 void RemoveRenderbufferInfo(GLuint client_id) { 874 renderbuffer_manager()->RemoveRenderbufferInfo(client_id); 875 } 876 877 // Gets the vertex attrib manager for the given vertex array. 878 VertexAttribManager* GetVertexAttribManager(GLuint client_id) { 879 VertexAttribManager* info = 880 vertex_array_manager()->GetVertexAttribManager(client_id); 881 return info; 882 } 883 884 // Removes the vertex attrib manager for the given vertex array. 885 void RemoveVertexAttribManager(GLuint client_id) { 886 vertex_array_manager()->RemoveVertexAttribManager(client_id); 887 } 888 889 // Creates a vertex attrib manager for the given vertex array. 890 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) { 891 return vertex_array_manager()->CreateVertexAttribManager( 892 client_id, service_id, group_->max_vertex_attribs()); 893 } 894 895 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name); 896 void DoBindUniformLocationCHROMIUM( 897 GLuint client_id, GLint location, const char* name); 898 899 error::Error GetAttribLocationHelper( 900 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 901 const std::string& name_str); 902 903 error::Error GetUniformLocationHelper( 904 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 905 const std::string& name_str); 906 907 // Helper for glShaderSource. 908 error::Error ShaderSourceHelper( 909 GLuint client_id, const char* data, uint32 data_size); 910 911 // Clear any textures used by the current program. 912 bool ClearUnclearedTextures(); 913 914 // Clear any uncleared level in texture. 915 // Returns false if there was a generated GL error. 916 bool ClearTexture(TextureManager::TextureInfo* info); 917 918 // Clears any uncleared attachments attached to the given frame buffer. 919 // Returns false if there was a generated GL error. 920 void ClearUnclearedAttachments( 921 GLenum target, FramebufferManager::FramebufferInfo* info); 922 923 // overridden from GLES2Decoder 924 virtual bool ClearLevel(unsigned service_id, 925 unsigned bind_target, 926 unsigned target, 927 int level, 928 unsigned format, 929 unsigned type, 930 int width, 931 int height, 932 bool is_texture_immutable) OVERRIDE; 933 934 // Restore all GL state that affects clearing. 935 void RestoreClearState(); 936 937 // Remembers the state of some capabilities. 938 // Returns: true if glEnable/glDisable should actually be called. 939 bool SetCapabilityState(GLenum cap, bool enabled); 940 941 // Check that the currently bound framebuffers are valid. 942 // Generates GL error if not. 943 bool CheckBoundFramebuffersValid(const char* func_name); 944 945 // Check if a framebuffer meets our requirements. 946 bool CheckFramebufferValid( 947 FramebufferManager::FramebufferInfo* framebuffer, 948 GLenum target, 949 const char* func_name); 950 951 // Checks if the current program exists and is valid. If not generates the 952 // appropriate GL error. Returns true if the current program is in a usable 953 // state. 954 bool CheckCurrentProgram(const char* function_name); 955 956 // Checks if the current program exists and is valid and that location is not 957 // -1. If the current program is not valid generates the appropriate GL 958 // error. Returns true if the current program is in a usable state and 959 // location is not -1. 960 bool CheckCurrentProgramForUniform(GLint location, const char* function_name); 961 962 // Gets the type of a uniform for a location in the current program. Sets GL 963 // errors if the current program is not valid. Returns true if the current 964 // program is valid and the location exists. Adjusts count so it 965 // does not overflow the uniform. 966 bool PrepForSetUniformByLocation( 967 GLint fake_location, const char* function_name, 968 GLint* real_location, GLenum* type, GLsizei* count); 969 970 // Gets the service id for any simulated backbuffer fbo. 971 GLuint GetBackbufferServiceId() const; 972 973 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv 974 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written); 975 // Same as GetHelper except for auto-generated state. 976 bool GetStateAsGLint(GLenum pname, GLint* params, GLsizei* num_written); 977 bool GetStateAsGLfloat(GLenum pname, GLfloat* params, GLsizei* num_written); 978 979 // Wrapper for glCreateProgram 980 bool CreateProgramHelper(GLuint client_id); 981 982 // Wrapper for glCreateShader 983 bool CreateShaderHelper(GLenum type, GLuint client_id); 984 985 // Wrapper for glActiveTexture 986 void DoActiveTexture(GLenum texture_unit); 987 988 // Wrapper for glAttachShader 989 void DoAttachShader(GLuint client_program_id, GLint client_shader_id); 990 991 // Wrapper for glBindBuffer since we need to track the current targets. 992 void DoBindBuffer(GLenum target, GLuint buffer); 993 994 // Wrapper for glBindFramebuffer since we need to track the current targets. 995 void DoBindFramebuffer(GLenum target, GLuint framebuffer); 996 997 // Wrapper for glBindRenderbuffer since we need to track the current targets. 998 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer); 999 1000 // Wrapper for glBindTexture since we need to track the current targets. 1001 void DoBindTexture(GLenum target, GLuint texture); 1002 1003 // Wrapper for glBindVertexArrayOES 1004 void DoBindVertexArrayOES(GLuint array); 1005 void EmulateVertexArrayState(); 1006 1007 // Wrapper for glBlitFramebufferEXT. 1008 void DoBlitFramebufferEXT( 1009 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 1010 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 1011 GLbitfield mask, GLenum filter); 1012 1013 // Wrapper for glBufferData. 1014 void DoBufferData( 1015 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage); 1016 1017 // Wrapper for glBufferSubData. 1018 void DoBufferSubData( 1019 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data); 1020 1021 // Wrapper for glCheckFramebufferStatus 1022 GLenum DoCheckFramebufferStatus(GLenum target); 1023 1024 // Wrapper for glClear 1025 error::Error DoClear(GLbitfield mask); 1026 1027 // Wrappers for various state. 1028 void DoDepthRangef(GLclampf znear, GLclampf zfar); 1029 void DoHint(GLenum target, GLenum mode); 1030 void DoSampleCoverage (GLclampf value, GLboolean invert); 1031 1032 // Wrapper for glCompileShader. 1033 void DoCompileShader(GLuint shader); 1034 1035 // Helper for DeleteSharedIdsCHROMIUM commands. 1036 void DoDeleteSharedIdsCHROMIUM( 1037 GLuint namespace_id, GLsizei n, const GLuint* ids); 1038 1039 // Wrapper for glDetachShader 1040 void DoDetachShader(GLuint client_program_id, GLint client_shader_id); 1041 1042 // Wrapper for glDisable 1043 void DoDisable(GLenum cap); 1044 1045 // Wrapper for glDisableVertexAttribArray. 1046 void DoDisableVertexAttribArray(GLuint index); 1047 1048 // Wrapper for glEnable 1049 void DoEnable(GLenum cap); 1050 1051 // Wrapper for glEnableVertexAttribArray. 1052 void DoEnableVertexAttribArray(GLuint index); 1053 1054 // Wrapper for glFinish. 1055 void DoFinish(); 1056 1057 // Wrapper for glFlush. 1058 void DoFlush(); 1059 1060 // Wrapper for glFramebufferRenderbufffer. 1061 void DoFramebufferRenderbuffer( 1062 GLenum target, GLenum attachment, GLenum renderbuffertarget, 1063 GLuint renderbuffer); 1064 1065 // Wrapper for glFramebufferTexture2D. 1066 void DoFramebufferTexture2D( 1067 GLenum target, GLenum attachment, GLenum textarget, GLuint texture, 1068 GLint level); 1069 1070 // Wrapper for glGenerateMipmap 1071 void DoGenerateMipmap(GLenum target); 1072 1073 // Helper for GenSharedIdsCHROMIUM commands. 1074 void DoGenSharedIdsCHROMIUM( 1075 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids); 1076 1077 // Wrapper for DoGetBooleanv. 1078 void DoGetBooleanv(GLenum pname, GLboolean* params); 1079 1080 // Wrapper for DoGetFloatv. 1081 void DoGetFloatv(GLenum pname, GLfloat* params); 1082 1083 // Wrapper for glGetFramebufferAttachmentParameteriv. 1084 void DoGetFramebufferAttachmentParameteriv( 1085 GLenum target, GLenum attachment, GLenum pname, GLint* params); 1086 1087 // Wrapper for glGetIntegerv. 1088 void DoGetIntegerv(GLenum pname, GLint* params); 1089 1090 // Gets the max value in a range in a buffer. 1091 GLuint DoGetMaxValueInBufferCHROMIUM( 1092 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset); 1093 1094 // Wrapper for glGetProgramiv. 1095 void DoGetProgramiv( 1096 GLuint program_id, GLenum pname, GLint* params); 1097 1098 // Wrapper for glRenderbufferParameteriv. 1099 void DoGetRenderbufferParameteriv( 1100 GLenum target, GLenum pname, GLint* params); 1101 1102 // Wrapper for glGetShaderiv 1103 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params); 1104 1105 // Wrappers for glGetVertexAttrib. 1106 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params); 1107 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params); 1108 1109 // Wrappers for glIsXXX functions. 1110 bool DoIsEnabled(GLenum cap); 1111 bool DoIsBuffer(GLuint client_id); 1112 bool DoIsFramebuffer(GLuint client_id); 1113 bool DoIsProgram(GLuint client_id); 1114 bool DoIsRenderbuffer(GLuint client_id); 1115 bool DoIsShader(GLuint client_id); 1116 bool DoIsTexture(GLuint client_id); 1117 bool DoIsVertexArrayOES(GLuint client_id); 1118 1119 // Wrapper for glLinkProgram 1120 void DoLinkProgram(GLuint program); 1121 1122 // Helper for RegisterSharedIdsCHROMIUM. 1123 void DoRegisterSharedIdsCHROMIUM( 1124 GLuint namespace_id, GLsizei n, const GLuint* ids); 1125 1126 // Wrapper for glRenderbufferStorage. 1127 void DoRenderbufferStorage( 1128 GLenum target, GLenum internalformat, GLsizei width, GLsizei height); 1129 1130 // Wrapper for glRenderbufferStorageMultisampleEXT. 1131 void DoRenderbufferStorageMultisample( 1132 GLenum target, GLsizei samples, GLenum internalformat, 1133 GLsizei width, GLsizei height); 1134 1135 // Wrapper for glReleaseShaderCompiler. 1136 void DoReleaseShaderCompiler() { } 1137 1138 // Wrappers for glTexParameter functions. 1139 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param); 1140 void DoTexParameteri(GLenum target, GLenum pname, GLint param); 1141 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params); 1142 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params); 1143 1144 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2 1145 // spec only these 2 functions can be used to set sampler uniforms. 1146 void DoUniform1i(GLint fake_location, GLint v0); 1147 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value); 1148 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value); 1149 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value); 1150 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value); 1151 1152 // Wrappers for glUniformfv because some drivers don't correctly accept 1153 // bool uniforms. 1154 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value); 1155 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value); 1156 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value); 1157 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value); 1158 1159 void DoUniformMatrix2fv( 1160 GLint fake_location, GLsizei count, GLboolean transpose, 1161 const GLfloat* value); 1162 void DoUniformMatrix3fv( 1163 GLint fake_location, GLsizei count, GLboolean transpose, 1164 const GLfloat* value); 1165 void DoUniformMatrix4fv( 1166 GLint fake_location, GLsizei count, GLboolean transpose, 1167 const GLfloat* value); 1168 1169 // Wrappers for glVertexAttrib?? 1170 void DoVertexAttrib1f(GLuint index, GLfloat v0); 1171 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1); 1172 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2); 1173 void DoVertexAttrib4f( 1174 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); 1175 void DoVertexAttrib1fv(GLuint index, const GLfloat *v); 1176 void DoVertexAttrib2fv(GLuint index, const GLfloat *v); 1177 void DoVertexAttrib3fv(GLuint index, const GLfloat *v); 1178 void DoVertexAttrib4fv(GLuint index, const GLfloat *v); 1179 1180 // Wrapper for glViewport 1181 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height); 1182 1183 // Wrapper for glUseProgram 1184 void DoUseProgram(GLuint program); 1185 1186 // Wrapper for glValidateProgram. 1187 void DoValidateProgram(GLuint program_client_id); 1188 1189 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker); 1190 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group); 1191 void DoPopGroupMarkerEXT(void); 1192 1193 // Gets the number of values that will be returned by glGetXXX. Returns 1194 // false if pname is unknown. 1195 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values); 1196 1197 // Gets the GLError and stores it in our wrapper. Effectively 1198 // this lets us peek at the error without losing it. 1199 GLenum PeekGLError(); 1200 1201 // Copies the real GL errors to the wrapper. This is so we can 1202 // make sure there are no native GL errors before calling some GL function 1203 // so that on return we know any error generated was for that specific 1204 // command. 1205 void CopyRealGLErrorsToWrapper(); 1206 1207 // Clear all real GL errors. This is to prevent the client from seeing any 1208 // errors caused by GL calls that it was not responsible for issuing. 1209 void ClearRealGLErrors(); 1210 1211 // Checks if the current program and vertex attributes are valid for drawing. 1212 bool IsDrawValid( 1213 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount); 1214 1215 // Returns true if successful, simulated will be true if attrib0 was 1216 // simulated. 1217 bool SimulateAttrib0( 1218 const char* function_name, GLuint max_vertex_accessed, bool* simulated); 1219 void RestoreStateForAttrib(GLuint attrib); 1220 1221 // Returns true if textures were set. 1222 bool SetBlackTextureForNonRenderableTextures(); 1223 void RestoreStateForNonRenderableTextures(); 1224 1225 // Returns true if GL_FIXED attribs were simulated. 1226 bool SimulateFixedAttribs( 1227 const char* function_name, 1228 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount); 1229 void RestoreStateForSimulatedFixedAttribs(); 1230 1231 // Handle DrawArrays and DrawElements for both instanced and non-instanced 1232 // cases (primcount is 0 for non-instanced). 1233 error::Error DoDrawArrays( 1234 const char* function_name, 1235 bool instanced, GLenum mode, GLint first, GLsizei count, 1236 GLsizei primcount); 1237 error::Error DoDrawElements( 1238 const char* function_name, 1239 bool instanced, GLenum mode, GLsizei count, GLenum type, 1240 int32 offset, GLsizei primcount); 1241 1242 // Gets the buffer id for a given target. 1243 BufferManager::BufferInfo* GetBufferInfoForTarget(GLenum target) { 1244 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER); 1245 if (target == GL_ARRAY_BUFFER) { 1246 return state_.bound_array_buffer; 1247 } else { 1248 return state_.vertex_attrib_manager->element_array_buffer(); 1249 } 1250 } 1251 1252 // Gets the texture id for a given target. 1253 TextureManager::TextureInfo* GetTextureInfoForTarget(GLenum target) { 1254 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 1255 TextureManager::TextureInfo* info = NULL; 1256 switch (target) { 1257 case GL_TEXTURE_2D: 1258 info = unit.bound_texture_2d; 1259 break; 1260 case GL_TEXTURE_CUBE_MAP: 1261 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1262 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1263 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1264 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1265 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1266 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1267 info = unit.bound_texture_cube_map; 1268 break; 1269 case GL_TEXTURE_EXTERNAL_OES: 1270 info = unit.bound_texture_external_oes; 1271 break; 1272 case GL_TEXTURE_RECTANGLE_ARB: 1273 info = unit.bound_texture_rectangle_arb; 1274 break; 1275 default: 1276 NOTREACHED(); 1277 return NULL; 1278 } 1279 return info; 1280 } 1281 1282 TextureManager::TextureInfo* GetTextureInfoForTargetUnlessDefault( 1283 GLenum target) { 1284 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 1285 if (!info) 1286 return NULL; 1287 if (info == texture_manager()->GetDefaultTextureInfo(target)) 1288 return NULL; 1289 return info; 1290 } 1291 1292 GLenum GetBindTargetForSamplerType(GLenum type) { 1293 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE || 1294 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB); 1295 switch (type) { 1296 case GL_SAMPLER_2D: 1297 return GL_TEXTURE_2D; 1298 case GL_SAMPLER_CUBE: 1299 return GL_TEXTURE_CUBE_MAP; 1300 case GL_SAMPLER_EXTERNAL_OES: 1301 return GL_TEXTURE_EXTERNAL_OES; 1302 case GL_SAMPLER_2D_RECT_ARB: 1303 return GL_TEXTURE_RECTANGLE_ARB; 1304 } 1305 1306 NOTREACHED(); 1307 return 0; 1308 } 1309 1310 // Gets the framebuffer info for a particular target. 1311 FramebufferManager::FramebufferInfo* GetFramebufferInfoForTarget( 1312 GLenum target) { 1313 FramebufferManager::FramebufferInfo* info = NULL; 1314 switch (target) { 1315 case GL_FRAMEBUFFER: 1316 case GL_DRAW_FRAMEBUFFER_EXT: 1317 info = state_.bound_draw_framebuffer; 1318 break; 1319 case GL_READ_FRAMEBUFFER_EXT: 1320 info = state_.bound_read_framebuffer; 1321 break; 1322 default: 1323 NOTREACHED(); 1324 break; 1325 } 1326 return info; 1327 } 1328 1329 RenderbufferManager::RenderbufferInfo* GetRenderbufferInfoForTarget( 1330 GLenum target) { 1331 RenderbufferManager::RenderbufferInfo* info = NULL; 1332 switch (target) { 1333 case GL_RENDERBUFFER: 1334 info = state_.bound_renderbuffer; 1335 break; 1336 default: 1337 NOTREACHED(); 1338 break; 1339 } 1340 return info; 1341 } 1342 1343 // Validates the program and location for a glGetUniform call and returns 1344 // a SizeResult setup to receive the result. Returns true if glGetUniform 1345 // should be called. 1346 bool GetUniformSetup( 1347 GLuint program, GLint fake_location, 1348 uint32 shm_id, uint32 shm_offset, 1349 error::Error* error, GLint* real_location, GLuint* service_id, 1350 void** result, GLenum* result_type); 1351 1352 // Computes the estimated memory used for the backbuffer and passes it to 1353 // the tracing system. 1354 size_t GetBackbufferMemoryTotal(); 1355 1356 // Returns true if the context was just lost due to e.g. GL_ARB_robustness. 1357 bool WasContextLost(); 1358 1359#if defined(OS_MACOSX) 1360 void ReleaseIOSurfaceForTexture(GLuint texture_id); 1361#endif 1362 1363 // Validates the combination of texture parameters. For example validates that 1364 // for a given format the specific type, level and targets are valid. 1365 // Synthesizes the correct GL error if invalid. Returns true if valid. 1366 bool ValidateTextureParameters( 1367 const char* function_name, 1368 GLenum target, GLenum format, GLenum type, GLint level); 1369 1370 bool ValidateCompressedTexDimensions( 1371 const char* function_name, 1372 GLint level, GLsizei width, GLsizei height, GLenum format); 1373 bool ValidateCompressedTexFuncData( 1374 const char* function_name, 1375 GLsizei width, GLsizei height, GLenum format, size_t size); 1376 bool ValidateCompressedTexSubDimensions( 1377 const char* function_name, 1378 GLenum target, GLint level, GLint xoffset, GLint yoffset, 1379 GLsizei width, GLsizei height, GLenum format, 1380 TextureManager::TextureInfo* texture); 1381 1382 void LogMessage(const std::string& msg); 1383 void RenderWarning(const std::string& msg); 1384 void PerformanceWarning(const std::string& msg); 1385 const std::string& GetLogPrefix() const; 1386 1387 const FeatureInfo::FeatureFlags& features() const { 1388 return feature_info_->feature_flags(); 1389 } 1390 1391 const FeatureInfo::Workarounds& workarounds() const { 1392 return feature_info_->workarounds(); 1393 } 1394 1395 bool ShouldDeferDraws() { 1396 return !offscreen_target_frame_buffer_.get() && 1397 state_.bound_draw_framebuffer == NULL && 1398 surface_->DeferDraws(); 1399 } 1400 1401 void ForceCompileShaderIfPending(ShaderManager::ShaderInfo* info); 1402 1403 // Generate a member function prototype for each command in an automated and 1404 // typesafe way. 1405 #define GLES2_CMD_OP(name) \ 1406 Error Handle ## name( \ 1407 uint32 immediate_data_size, \ 1408 const gles2::name& args); \ 1409 1410 GLES2_COMMAND_LIST(GLES2_CMD_OP) 1411 1412 #undef GLES2_CMD_OP 1413 1414 // The GL context this decoder renders to on behalf of the client. 1415 scoped_refptr<gfx::GLSurface> surface_; 1416 scoped_refptr<gfx::GLContext> context_; 1417 1418 // The ContextGroup for this decoder uses to track resources. 1419 ContextGroup::Ref group_; 1420 1421 // All the state for this context. 1422 ContextState state_; 1423 1424 // A parent decoder can access this decoders saved offscreen frame buffer. 1425 // The parent pointer is reset if the parent is destroyed. 1426 base::WeakPtr<GLES2DecoderImpl> parent_; 1427 1428 // Current width and height of the offscreen frame buffer. 1429 gfx::Size offscreen_size_; 1430 1431 // Current GL error bits. 1432 uint32 error_bits_; 1433 1434 // Util to help with GL. 1435 GLES2Util util_; 1436 1437 // unpack flip y as last set by glPixelStorei 1438 bool unpack_flip_y_; 1439 1440 // unpack (un)premultiply alpha as last set by glPixelStorei 1441 bool unpack_premultiply_alpha_; 1442 bool unpack_unpremultiply_alpha_; 1443 1444 // Default vertex attribs manager, used when no VAOs are bound. 1445 VertexAttribManager::Ref default_vertex_attrib_manager_; 1446 1447 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not). 1448 GLuint attrib_0_buffer_id_; 1449 1450 // The value currently in attrib_0. 1451 VertexAttribManager::VertexAttribInfo::Vec4 attrib_0_value_; 1452 1453 // Whether or not the attrib_0 buffer holds the attrib_0_value. 1454 bool attrib_0_buffer_matches_value_; 1455 1456 // The size of attrib 0. 1457 GLsizei attrib_0_size_; 1458 1459 // The buffer used to simulate GL_FIXED attribs. 1460 GLuint fixed_attrib_buffer_id_; 1461 1462 // The size of fiixed attrib buffer. 1463 GLsizei fixed_attrib_buffer_size_; 1464 1465 // state saved for clearing so we can clear render buffers and then 1466 // restore to these values. 1467 bool clear_state_dirty_; 1468 1469 // The offscreen frame buffer that the client renders to. With EGL, the 1470 // depth and stencil buffers are separate. With regular GL there is a single 1471 // packed depth stencil buffer in offscreen_target_depth_render_buffer_. 1472 // offscreen_target_stencil_render_buffer_ is unused. 1473 scoped_ptr<FrameBuffer> offscreen_target_frame_buffer_; 1474 scoped_ptr<Texture> offscreen_target_color_texture_; 1475 scoped_ptr<RenderBuffer> offscreen_target_color_render_buffer_; 1476 scoped_ptr<RenderBuffer> offscreen_target_depth_render_buffer_; 1477 scoped_ptr<RenderBuffer> offscreen_target_stencil_render_buffer_; 1478 GLenum offscreen_target_color_format_; 1479 GLenum offscreen_target_depth_format_; 1480 GLenum offscreen_target_stencil_format_; 1481 GLsizei offscreen_target_samples_; 1482 GLboolean offscreen_target_buffer_preserved_; 1483 1484 // The copy that is saved when SwapBuffers is called. 1485 scoped_ptr<FrameBuffer> offscreen_saved_frame_buffer_; 1486 scoped_ptr<Texture> offscreen_saved_color_texture_; 1487 TextureManager::TextureInfo::Ref offscreen_saved_color_texture_info_; 1488 1489 // The copy that is used as the destination for multi-sample resolves. 1490 scoped_ptr<FrameBuffer> offscreen_resolved_frame_buffer_; 1491 scoped_ptr<Texture> offscreen_resolved_color_texture_; 1492 GLenum offscreen_saved_color_format_; 1493 1494 scoped_ptr<QueryManager> query_manager_; 1495 1496 scoped_ptr<VertexArrayManager> vertex_array_manager_; 1497 1498 base::Callback<void(gfx::Size)> resize_callback_; 1499 1500 MsgCallback msg_callback_; 1501 1502 StreamTextureManager* stream_texture_manager_; 1503 1504 // The format of the back buffer_ 1505 GLenum back_buffer_color_format_; 1506 bool back_buffer_has_depth_; 1507 bool back_buffer_has_stencil_; 1508 1509 bool teximage2d_faster_than_texsubimage2d_; 1510 1511 // The last error message set. 1512 std::string last_error_; 1513 1514 int log_message_count_; 1515 1516 // The current decoder error. 1517 error::Error current_decoder_error_; 1518 1519 DebugMarkerManager debug_marker_manager_; 1520 std::string this_in_hex_; 1521 1522 bool use_shader_translator_; 1523 scoped_refptr<ShaderTranslator> vertex_translator_; 1524 scoped_refptr<ShaderTranslator> fragment_translator_; 1525 1526 DisallowedFeatures disallowed_features_; 1527 1528 // Cached from ContextGroup 1529 const Validators* validators_; 1530 FeatureInfo::Ref feature_info_; 1531 1532 // This indicates all the following texSubImage2D calls that are part of the 1533 // failed texImage2D call should be ignored. 1534 bool tex_image_2d_failed_; 1535 1536 int frame_number_; 1537 1538 bool has_robustness_extension_; 1539 GLenum reset_status_; 1540 1541 // These flags are used to override the state of the shared feature_info_ 1542 // member. Because the same FeatureInfo instance may be shared among many 1543 // contexts, the assumptions on the availablity of extensions in WebGL 1544 // contexts may be broken. These flags override the shared state to preserve 1545 // WebGL semantics. 1546 bool force_webgl_glsl_validation_; 1547 bool derivatives_explicitly_enabled_; 1548 1549 bool compile_shader_always_succeeds_; 1550 1551#if defined(OS_MACOSX) 1552 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap; 1553 TextureToIOSurfaceMap texture_to_io_surface_map_; 1554#endif 1555 1556 typedef std::vector<GLES2DecoderImpl*> ChildList; 1557 ChildList children_; 1558 1559 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_; 1560 1561 // Cached values of the currently assigned viewport dimensions. 1562 GLsizei viewport_max_width_; 1563 GLsizei viewport_max_height_; 1564 1565 // Command buffer stats. 1566 int texture_upload_count_; 1567 base::TimeDelta total_texture_upload_time_; 1568 base::TimeDelta total_processing_commands_time_; 1569 1570 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); 1571}; 1572 1573ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(GLES2DecoderImpl* decoder) 1574 : decoder_(decoder) { 1575 decoder_->CopyRealGLErrorsToWrapper(); 1576} 1577 1578ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() { 1579 decoder_->ClearRealGLErrors(); 1580} 1581 1582ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder, 1583 GLuint id) 1584 : decoder_(decoder) { 1585 ScopedGLErrorSuppressor suppressor(decoder_); 1586 1587 // TODO(apatrick): Check if there are any other states that need to be reset 1588 // before binding a new texture. 1589 glActiveTexture(GL_TEXTURE0); 1590 glBindTexture(GL_TEXTURE_2D, id); 1591} 1592 1593ScopedTexture2DBinder::~ScopedTexture2DBinder() { 1594 ScopedGLErrorSuppressor suppressor(decoder_); 1595 decoder_->RestoreCurrentTexture2DBindings(); 1596} 1597 1598ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, 1599 GLuint id) 1600 : decoder_(decoder) { 1601 ScopedGLErrorSuppressor suppressor(decoder_); 1602 glBindRenderbufferEXT(GL_RENDERBUFFER, id); 1603} 1604 1605ScopedRenderBufferBinder::~ScopedRenderBufferBinder() { 1606 ScopedGLErrorSuppressor suppressor(decoder_); 1607 decoder_->RestoreCurrentRenderbufferBindings(); 1608} 1609 1610ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, 1611 GLuint id) 1612 : decoder_(decoder) { 1613 ScopedGLErrorSuppressor suppressor(decoder_); 1614 glBindFramebufferEXT(GL_FRAMEBUFFER, id); 1615} 1616 1617ScopedFrameBufferBinder::~ScopedFrameBufferBinder() { 1618 ScopedGLErrorSuppressor suppressor(decoder_); 1619 decoder_->RestoreCurrentFramebufferBindings(); 1620} 1621 1622ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder( 1623 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal) 1624 : decoder_(decoder) { 1625 resolve_and_bind_ = (decoder_->offscreen_target_frame_buffer_.get() && 1626 decoder_->IsOffscreenBufferMultisampled() && 1627 (!decoder_->state_.bound_read_framebuffer.get() || 1628 enforce_internal_framebuffer)); 1629 if (!resolve_and_bind_) 1630 return; 1631 1632 ScopedGLErrorSuppressor suppressor(decoder_); 1633 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 1634 decoder_->offscreen_target_frame_buffer_->id()); 1635 GLuint targetid; 1636 if (internal) { 1637 if (!decoder_->offscreen_resolved_frame_buffer_.get()) { 1638 decoder_->offscreen_resolved_frame_buffer_.reset( 1639 new FrameBuffer(decoder_)); 1640 decoder_->offscreen_resolved_frame_buffer_->Create(); 1641 decoder_->offscreen_resolved_color_texture_.reset(new Texture(decoder_)); 1642 decoder_->offscreen_resolved_color_texture_->Create(); 1643 1644 DCHECK(decoder_->offscreen_saved_color_format_); 1645 decoder_->offscreen_resolved_color_texture_->AllocateStorage( 1646 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_); 1647 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture( 1648 decoder_->offscreen_resolved_color_texture_.get()); 1649 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() != 1650 GL_FRAMEBUFFER_COMPLETE) { 1651 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed " 1652 << "because offscreen resolved FBO was incomplete."; 1653 return; 1654 } 1655 } 1656 targetid = decoder_->offscreen_resolved_frame_buffer_->id(); 1657 } else { 1658 targetid = decoder_->offscreen_saved_frame_buffer_->id(); 1659 } 1660 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid); 1661 const int width = decoder_->offscreen_size_.width(); 1662 const int height = decoder_->offscreen_size_.height(); 1663 glDisable(GL_SCISSOR_TEST); 1664 if (GLES2Decoder::IsAngle()) { 1665 glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height, 1666 GL_COLOR_BUFFER_BIT, GL_NEAREST); 1667 } else { 1668 glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, 1669 GL_COLOR_BUFFER_BIT, GL_NEAREST); 1670 } 1671 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid); 1672} 1673 1674ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() { 1675 if (!resolve_and_bind_) 1676 return; 1677 1678 ScopedGLErrorSuppressor suppressor(decoder_); 1679 decoder_->RestoreCurrentFramebufferBindings(); 1680 if (decoder_->state_.enable_flags.scissor_test) { 1681 glEnable(GL_SCISSOR_TEST); 1682 } 1683} 1684 1685ScopedTextureUploadTimer::ScopedTextureUploadTimer(GLES2DecoderImpl* decoder) 1686 : decoder_(decoder), 1687 begin_time_(base::TimeTicks::HighResNow()) { 1688} 1689 1690ScopedTextureUploadTimer::~ScopedTextureUploadTimer() { 1691 decoder_->texture_upload_count_++; 1692 decoder_->total_texture_upload_time_ += 1693 base::TimeTicks::HighResNow() - begin_time_; 1694} 1695 1696Texture::Texture(GLES2DecoderImpl* decoder) 1697 : decoder_(decoder), 1698 memory_tracker_(decoder->GetContextGroup()->memory_tracker()), 1699 id_(0) { 1700} 1701 1702Texture::~Texture() { 1703 // This does not destroy the render texture because that would require that 1704 // the associated GL context was current. Just check that it was explicitly 1705 // destroyed. 1706 DCHECK_EQ(id_, 0u); 1707} 1708 1709void Texture::Create() { 1710 ScopedGLErrorSuppressor suppressor(decoder_); 1711 Destroy(); 1712 glGenTextures(1, &id_); 1713 ScopedTexture2DBinder binder(decoder_, id_); 1714 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1715 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1716 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1717 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1718 1719 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is 1720 // never called on an offscreen context, no data will ever be uploaded to the 1721 // saved offscreen color texture (it is deferred until to when SwapBuffers 1722 // is called). My idea is that some nvidia drivers might have a bug where 1723 // deleting a texture that has never been populated might cause a 1724 // crash. 1725 glTexImage2D( 1726 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 1727 memory_tracker_.UpdateMemRepresented(16u * 16u * 4u); 1728} 1729 1730bool Texture::AllocateStorage(const gfx::Size& size, GLenum format) { 1731 DCHECK_NE(id_, 0u); 1732 ScopedGLErrorSuppressor suppressor(decoder_); 1733 ScopedTexture2DBinder binder(decoder_, id_); 1734 1735 WrappedTexImage2D(GL_TEXTURE_2D, 1736 0, // mip level 1737 format, 1738 size.width(), 1739 size.height(), 1740 0, // border 1741 format, 1742 GL_UNSIGNED_BYTE, 1743 NULL); 1744 1745 size_ = size; 1746 1747 bool success = glGetError() == GL_NO_ERROR; 1748 if (success) { 1749 uint32 image_size = 0; 1750 GLES2Util::ComputeImageDataSizes( 1751 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 4, &image_size, 1752 NULL, NULL); 1753 memory_tracker_.UpdateMemRepresented(image_size); 1754 } 1755 return success; 1756} 1757 1758void Texture::Copy(const gfx::Size& size, GLenum format) { 1759 DCHECK_NE(id_, 0u); 1760 ScopedGLErrorSuppressor suppressor(decoder_); 1761 ScopedTexture2DBinder binder(decoder_, id_); 1762 glCopyTexImage2D(GL_TEXTURE_2D, 1763 0, // level 1764 format, 1765 0, 0, 1766 size.width(), 1767 size.height(), 1768 0); // border 1769} 1770 1771void Texture::Destroy() { 1772 if (id_ != 0) { 1773 ScopedGLErrorSuppressor suppressor(decoder_); 1774 glDeleteTextures(1, &id_); 1775 id_ = 0; 1776 memory_tracker_.UpdateMemRepresented(0); 1777 } 1778} 1779 1780void Texture::Invalidate() { 1781 id_ = 0; 1782} 1783 1784RenderBuffer::RenderBuffer(GLES2DecoderImpl* decoder) 1785 : decoder_(decoder), 1786 memory_tracker_(decoder->GetContextGroup()->memory_tracker()), 1787 id_(0) { 1788} 1789 1790RenderBuffer::~RenderBuffer() { 1791 // This does not destroy the render buffer because that would require that 1792 // the associated GL context was current. Just check that it was explicitly 1793 // destroyed. 1794 DCHECK_EQ(id_, 0u); 1795} 1796 1797void RenderBuffer::Create() { 1798 ScopedGLErrorSuppressor suppressor(decoder_); 1799 Destroy(); 1800 glGenRenderbuffersEXT(1, &id_); 1801} 1802 1803bool RenderBuffer::AllocateStorage(const gfx::Size& size, GLenum format, 1804 GLsizei samples) { 1805 ScopedGLErrorSuppressor suppressor(decoder_); 1806 ScopedRenderBufferBinder binder(decoder_, id_); 1807 if (samples <= 1) { 1808 glRenderbufferStorageEXT(GL_RENDERBUFFER, 1809 format, 1810 size.width(), 1811 size.height()); 1812 } else { 1813 if (GLES2Decoder::IsAngle()) { 1814 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1815 samples, 1816 format, 1817 size.width(), 1818 size.height()); 1819 } else { 1820 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 1821 samples, 1822 format, 1823 size.width(), 1824 size.height()); 1825 } 1826 } 1827 bool success = glGetError() == GL_NO_ERROR; 1828 if (success) { 1829 memory_tracker_.UpdateMemRepresented( 1830 size.width() * size.height() * samples * 1831 GLES2Util::RenderbufferBytesPerPixel(format)); 1832 } 1833 return success; 1834} 1835 1836void RenderBuffer::Destroy() { 1837 if (id_ != 0) { 1838 ScopedGLErrorSuppressor suppressor(decoder_); 1839 glDeleteRenderbuffersEXT(1, &id_); 1840 id_ = 0; 1841 memory_tracker_.UpdateMemRepresented(0); 1842 } 1843} 1844 1845void RenderBuffer::Invalidate() { 1846 id_ = 0; 1847} 1848 1849FrameBuffer::FrameBuffer(GLES2DecoderImpl* decoder) 1850 : decoder_(decoder), 1851 id_(0) { 1852} 1853 1854FrameBuffer::~FrameBuffer() { 1855 // This does not destroy the frame buffer because that would require that 1856 // the associated GL context was current. Just check that it was explicitly 1857 // destroyed. 1858 DCHECK_EQ(id_, 0u); 1859} 1860 1861void FrameBuffer::Create() { 1862 ScopedGLErrorSuppressor suppressor(decoder_); 1863 Destroy(); 1864 glGenFramebuffersEXT(1, &id_); 1865} 1866 1867void FrameBuffer::AttachRenderTexture(Texture* texture) { 1868 DCHECK_NE(id_, 0u); 1869 ScopedGLErrorSuppressor suppressor(decoder_); 1870 ScopedFrameBufferBinder binder(decoder_, id_); 1871 GLuint attach_id = texture ? texture->id() : 0; 1872 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, 1873 GL_COLOR_ATTACHMENT0, 1874 GL_TEXTURE_2D, 1875 attach_id, 1876 0); 1877} 1878 1879void FrameBuffer::AttachRenderBuffer(GLenum target, 1880 RenderBuffer* render_buffer) { 1881 DCHECK_NE(id_, 0u); 1882 ScopedGLErrorSuppressor suppressor(decoder_); 1883 ScopedFrameBufferBinder binder(decoder_, id_); 1884 GLuint attach_id = render_buffer ? render_buffer->id() : 0; 1885 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, 1886 target, 1887 GL_RENDERBUFFER, 1888 attach_id); 1889} 1890 1891void FrameBuffer::Destroy() { 1892 if (id_ != 0) { 1893 ScopedGLErrorSuppressor suppressor(decoder_); 1894 glDeleteFramebuffersEXT(1, &id_); 1895 id_ = 0; 1896 } 1897} 1898 1899void FrameBuffer::Invalidate() { 1900 id_ = 0; 1901} 1902 1903GLenum FrameBuffer::CheckStatus() { 1904 DCHECK_NE(id_, 0u); 1905 ScopedGLErrorSuppressor suppressor(decoder_); 1906 ScopedFrameBufferBinder binder(decoder_, id_); 1907 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 1908} 1909 1910GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) { 1911 return new GLES2DecoderImpl(group); 1912} 1913 1914GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) 1915 : GLES2Decoder(), 1916 group_(group), 1917 error_bits_(0), 1918 unpack_flip_y_(false), 1919 unpack_premultiply_alpha_(false), 1920 unpack_unpremultiply_alpha_(false), 1921 attrib_0_buffer_id_(0), 1922 attrib_0_buffer_matches_value_(true), 1923 attrib_0_size_(0), 1924 fixed_attrib_buffer_id_(0), 1925 fixed_attrib_buffer_size_(0), 1926 clear_state_dirty_(true), 1927 offscreen_target_color_format_(0), 1928 offscreen_target_depth_format_(0), 1929 offscreen_target_stencil_format_(0), 1930 offscreen_target_samples_(0), 1931 offscreen_target_buffer_preserved_(true), 1932 offscreen_saved_color_format_(0), 1933 stream_texture_manager_(NULL), 1934 back_buffer_color_format_(0), 1935 back_buffer_has_depth_(false), 1936 back_buffer_has_stencil_(false), 1937 teximage2d_faster_than_texsubimage2d_(true), 1938 log_message_count_(0), 1939 current_decoder_error_(error::kNoError), 1940 use_shader_translator_(true), 1941 validators_(group_->feature_info()->validators()), 1942 feature_info_(group_->feature_info()), 1943 tex_image_2d_failed_(false), 1944 frame_number_(0), 1945 has_robustness_extension_(false), 1946 reset_status_(GL_NO_ERROR), 1947 force_webgl_glsl_validation_(false), 1948 derivatives_explicitly_enabled_(false), 1949 compile_shader_always_succeeds_(false), 1950 viewport_max_width_(0), 1951 viewport_max_height_(0), 1952 texture_upload_count_(0) { 1953 DCHECK(group); 1954 1955 GLES2DecoderImpl* this_temp = this; 1956 this_in_hex_ = HexEncode(&this_temp, sizeof(this_temp)); 1957 1958 attrib_0_value_.v[0] = 0.0f; 1959 attrib_0_value_.v[1] = 0.0f; 1960 attrib_0_value_.v[2] = 0.0f; 1961 attrib_0_value_.v[3] = 1.0f; 1962 1963 // The shader translator is used for WebGL even when running on EGL 1964 // because additional restrictions are needed (like only enabling 1965 // GL_OES_standard_derivatives on demand). It is used for the unit 1966 // tests because 1967 // GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes the 1968 // empty string to CompileShader and this is not a valid shader. 1969 // TODO(apatrick): fix this test. 1970 if ((gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 && 1971 !features().chromium_webglsl && !force_webgl_glsl_validation_) || 1972 gfx::GetGLImplementation() == gfx::kGLImplementationMockGL || 1973 CommandLine::ForCurrentProcess()->HasSwitch( 1974 switches::kDisableGLSLTranslator)) { 1975 use_shader_translator_ = false; 1976 } 1977 1978 // TODO(gman): Consider setting this based on GPU and/or driver. 1979 if (IsAngle()) { 1980 teximage2d_faster_than_texsubimage2d_ = false; 1981 } 1982} 1983 1984GLES2DecoderImpl::~GLES2DecoderImpl() { 1985} 1986 1987bool GLES2DecoderImpl::Initialize( 1988 const scoped_refptr<gfx::GLSurface>& surface, 1989 const scoped_refptr<gfx::GLContext>& context, 1990 bool offscreen, 1991 const gfx::Size& size, 1992 const DisallowedFeatures& disallowed_features, 1993 const char* allowed_extensions, 1994 const std::vector<int32>& attribs) { 1995 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize"); 1996 DCHECK(context->IsCurrent(surface.get())); 1997 DCHECK(!context_.get()); 1998 1999 if (CommandLine::ForCurrentProcess()->HasSwitch( 2000 switches::kEnableGPUDebugging)) { 2001 set_debug(true); 2002 } 2003 2004 if (CommandLine::ForCurrentProcess()->HasSwitch( 2005 switches::kEnableGPUCommandLogging)) { 2006 set_log_commands(true); 2007 } 2008 2009 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch( 2010 switches::kCompileShaderAlwaysSucceeds); 2011 2012 2013 // Take ownership of the context and surface. The surface can be replaced with 2014 // SetSurface. 2015 context_ = context; 2016 surface_ = surface; 2017 2018 if (!group_->Initialize(disallowed_features, allowed_extensions)) { 2019 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group " 2020 << "failed to initialize."; 2021 group_ = NULL; // Must not destroy ContextGroup if it is not initialized. 2022 Destroy(true); 2023 return false; 2024 } 2025 CHECK_GL_ERROR(); 2026 2027 disallowed_features_ = disallowed_features; 2028 2029 default_vertex_attrib_manager_ = new VertexAttribManager(); 2030 default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs()); 2031 2032 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call 2033 DoBindVertexArrayOES(0); 2034 2035 query_manager_.reset(new QueryManager(this, feature_info_)); 2036 vertex_array_manager_.reset(new VertexArrayManager()); 2037 2038 util_.set_num_compressed_texture_formats( 2039 validators_->compressed_texture_format.GetValues().size()); 2040 2041 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 2042 // We have to enable vertex array 0 on OpenGL or it won't render. Note that 2043 // OpenGL ES 2.0 does not have this issue. 2044 glEnableVertexAttribArray(0); 2045 } 2046 glGenBuffersARB(1, &attrib_0_buffer_id_); 2047 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_); 2048 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL); 2049 glBindBuffer(GL_ARRAY_BUFFER, 0); 2050 glGenBuffersARB(1, &fixed_attrib_buffer_id_); 2051 2052 state_.texture_units.resize(group_->max_texture_units()); 2053 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) { 2054 glActiveTexture(GL_TEXTURE0 + tt); 2055 // We want the last bind to be 2D. 2056 TextureManager::TextureInfo* info; 2057 if (features().oes_egl_image_external) { 2058 info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_EXTERNAL_OES); 2059 state_.texture_units[tt].bound_texture_external_oes = info; 2060 glBindTexture(GL_TEXTURE_EXTERNAL_OES, info->service_id()); 2061 } 2062 if (features().arb_texture_rectangle) { 2063 info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_RECTANGLE_ARB); 2064 state_.texture_units[tt].bound_texture_rectangle_arb = info; 2065 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, info->service_id()); 2066 } 2067 info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP); 2068 state_.texture_units[tt].bound_texture_cube_map = info; 2069 glBindTexture(GL_TEXTURE_CUBE_MAP, info->service_id()); 2070 info = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D); 2071 state_.texture_units[tt].bound_texture_2d = info; 2072 glBindTexture(GL_TEXTURE_2D, info->service_id()); 2073 } 2074 glActiveTexture(GL_TEXTURE0); 2075 CHECK_GL_ERROR(); 2076 2077 ContextCreationAttribParser attrib_parser; 2078 if (!attrib_parser.Parse(attribs)) 2079 return false; 2080 2081 // These are NOT if the back buffer has these proprorties. They are 2082 // if we want the command buffer to enforce them regardless of what 2083 // the real backbuffer is assuming the real back buffer gives us more than 2084 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll 2085 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we 2086 // can't do anything about that. 2087 2088 GLint v = 0; 2089 glGetIntegerv(GL_ALPHA_BITS, &v); 2090 // This checks if the user requested RGBA and we have RGBA then RGBA. If the 2091 // user requested RGB then RGB. If the user did not specify a preference than 2092 // use whatever we were given. Same for DEPTH and STENCIL. 2093 back_buffer_color_format_ = 2094 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB; 2095 glGetIntegerv(GL_DEPTH_BITS, &v); 2096 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0; 2097 glGetIntegerv(GL_STENCIL_BITS, &v); 2098 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0; 2099 2100 if (offscreen) { 2101 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 && 2102 (context_->HasExtension("GL_EXT_framebuffer_multisample") || 2103 context_->HasExtension("GL_ANGLE_framebuffer_multisample"))) { 2104 // Per ext_framebuffer_multisample spec, need max bound on sample count. 2105 // max_sample_count must be initialized to a sane value. If 2106 // glGetIntegerv() throws a GL error, it leaves its argument unchanged. 2107 GLint max_sample_count = 1; 2108 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count); 2109 offscreen_target_samples_ = std::min(attrib_parser.samples_, 2110 max_sample_count); 2111 } else { 2112 offscreen_target_samples_ = 1; 2113 } 2114 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_; 2115 2116 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { 2117 const bool rgb8_supported = 2118 context_->HasExtension("GL_OES_rgb8_rgba8"); 2119 // The only available default render buffer formats in GLES2 have very 2120 // little precision. Don't enable multisampling unless 8-bit render 2121 // buffer formats are available--instead fall back to 8-bit textures. 2122 if (rgb8_supported && offscreen_target_samples_ > 1) { 2123 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ? 2124 GL_RGBA8 : GL_RGB8; 2125 } else { 2126 offscreen_target_samples_ = 1; 2127 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ? 2128 GL_RGBA : GL_RGB; 2129 } 2130 2131 // ANGLE only supports packed depth/stencil formats, so use it if it is 2132 // available. 2133 const bool depth24_stencil8_supported = 2134 context_->HasExtension("GL_OES_packed_depth_stencil"); 2135 VLOG(1) << "GL_OES_packed_depth_stencil " 2136 << (depth24_stencil8_supported ? "" : "not ") << "supported."; 2137 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) && 2138 depth24_stencil8_supported) { 2139 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8; 2140 offscreen_target_stencil_format_ = 0; 2141 } else { 2142 // It may be the case that this depth/stencil combination is not 2143 // supported, but this will be checked later by CheckFramebufferStatus. 2144 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ? 2145 GL_DEPTH_COMPONENT16 : 0; 2146 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ? 2147 GL_STENCIL_INDEX8 : 0; 2148 } 2149 } else { 2150 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ? 2151 GL_RGBA : GL_RGB; 2152 2153 // If depth is requested at all, use the packed depth stencil format if 2154 // it's available, as some desktop GL drivers don't support any non-packed 2155 // formats for depth attachments. 2156 const bool depth24_stencil8_supported = 2157 context_->HasExtension("GL_EXT_packed_depth_stencil"); 2158 VLOG(1) << "GL_EXT_packed_depth_stencil " 2159 << (depth24_stencil8_supported ? "" : "not ") << "supported."; 2160 2161 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) && 2162 depth24_stencil8_supported) { 2163 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8; 2164 offscreen_target_stencil_format_ = 0; 2165 } else { 2166 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ? 2167 GL_DEPTH_COMPONENT : 0; 2168 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ? 2169 GL_STENCIL_INDEX : 0; 2170 } 2171 } 2172 2173 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ? 2174 GL_RGBA : GL_RGB; 2175 2176 // Create the target frame buffer. This is the one that the client renders 2177 // directly to. 2178 offscreen_target_frame_buffer_.reset(new FrameBuffer(this)); 2179 offscreen_target_frame_buffer_->Create(); 2180 // Due to GLES2 format limitations, either the color texture (for 2181 // non-multisampling) or the color render buffer (for multisampling) will be 2182 // attached to the offscreen frame buffer. The render buffer has more 2183 // limited formats available to it, but the texture can't do multisampling. 2184 if (IsOffscreenBufferMultisampled()) { 2185 offscreen_target_color_render_buffer_.reset(new RenderBuffer(this)); 2186 offscreen_target_color_render_buffer_->Create(); 2187 } else { 2188 offscreen_target_color_texture_.reset(new Texture(this)); 2189 offscreen_target_color_texture_->Create(); 2190 } 2191 offscreen_target_depth_render_buffer_.reset(new RenderBuffer(this)); 2192 offscreen_target_depth_render_buffer_->Create(); 2193 offscreen_target_stencil_render_buffer_.reset(new RenderBuffer(this)); 2194 offscreen_target_stencil_render_buffer_->Create(); 2195 2196 // Create the saved offscreen texture. The target frame buffer is copied 2197 // here when SwapBuffers is called. 2198 offscreen_saved_frame_buffer_.reset(new FrameBuffer(this)); 2199 offscreen_saved_frame_buffer_->Create(); 2200 // 2201 offscreen_saved_color_texture_.reset(new Texture(this)); 2202 offscreen_saved_color_texture_->Create(); 2203 2204 // Allocate the render buffers at their initial size and check the status 2205 // of the frame buffers is okay. 2206 if (!ResizeOffscreenFrameBuffer(size)) { 2207 LOG(ERROR) << "Could not allocate offscreen buffer storage."; 2208 Destroy(true); 2209 return false; 2210 } 2211 2212 // Bind to the new default frame buffer (the offscreen target frame buffer). 2213 // This should now be associated with ID zero. 2214 DoBindFramebuffer(GL_FRAMEBUFFER, 0); 2215 } 2216 2217 // Clear the backbuffer. 2218 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 2219 2220 // OpenGL ES 2.0 implicitly enables the desktop GL capability 2221 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact 2222 // isn't well documented; it was discovered in the Khronos OpenGL ES 2223 // mailing list archives. It also implicitly enables the desktop GL 2224 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord 2225 // variable in fragment shaders. 2226 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 2227 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); 2228 glEnable(GL_POINT_SPRITE); 2229 } 2230 2231 has_robustness_extension_ = 2232 context->HasExtension("GL_ARB_robustness") || 2233 context->HasExtension("GL_EXT_robustness"); 2234 2235 if (!InitializeShaderTranslator()) { 2236 return false; 2237 } 2238 2239 state_.viewport_width = size.width(); 2240 state_.viewport_height = size.height(); 2241 2242 GLint viewport_params[4] = { 0 }; 2243 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params); 2244 viewport_max_width_ = viewport_params[0]; 2245 viewport_max_height_ = viewport_params[1]; 2246 2247 state_.scissor_width = state_.viewport_width; 2248 state_.scissor_height = state_.viewport_height; 2249 2250 // Set all the default state because some GL drivers get it wrong. 2251 state_.InitCapabilities(); 2252 state_.InitState(); 2253 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit); 2254 glHint(GL_GENERATE_MIPMAP_HINT, state_.hint_generate_mipmap); 2255 glPixelStorei(GL_PACK_ALIGNMENT, state_.pack_alignment); 2256 glPixelStorei(GL_UNPACK_ALIGNMENT, state_.unpack_alignment); 2257 2258 DoBindBuffer(GL_ARRAY_BUFFER, 0); 2259 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 2260 DoBindFramebuffer(GL_FRAMEBUFFER, 0); 2261 DoBindRenderbuffer(GL_RENDERBUFFER, 0); 2262 2263 // AMD and Intel drivers on Mac OS apparently get gl_PointCoord 2264 // backward from the spec and this setting makes them work 2265 // correctly. rdar://problem/11883495 2266 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) { 2267 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); 2268 } 2269 2270 return true; 2271} 2272 2273void GLES2DecoderImpl::UpdateCapabilities() { 2274 util_.set_num_compressed_texture_formats( 2275 validators_->compressed_texture_format.GetValues().size()); 2276 util_.set_num_shader_binary_formats( 2277 validators_->shader_binary_format.GetValues().size()); 2278} 2279 2280bool GLES2DecoderImpl::InitializeShaderTranslator() { 2281 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator"); 2282 2283 // Re-check the state of use_shader_translator_ each time this is called. 2284 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 && 2285 (features().chromium_webglsl || force_webgl_glsl_validation_) && 2286 !use_shader_translator_) { 2287 use_shader_translator_ = true; 2288 } 2289 if (!use_shader_translator_) { 2290 return true; 2291 } 2292 ShBuiltInResources resources; 2293 ShInitBuiltInResources(&resources); 2294 resources.MaxVertexAttribs = group_->max_vertex_attribs(); 2295 resources.MaxVertexUniformVectors = 2296 group_->max_vertex_uniform_vectors(); 2297 resources.MaxVaryingVectors = group_->max_varying_vectors(); 2298 resources.MaxVertexTextureImageUnits = 2299 group_->max_vertex_texture_image_units(); 2300 resources.MaxCombinedTextureImageUnits = group_->max_texture_units(); 2301 resources.MaxTextureImageUnits = group_->max_texture_image_units(); 2302 resources.MaxFragmentUniformVectors = 2303 group_->max_fragment_uniform_vectors(); 2304 resources.MaxDrawBuffers = 1; 2305 2306 if (force_webgl_glsl_validation_) { 2307 resources.OES_standard_derivatives = derivatives_explicitly_enabled_; 2308 } else { 2309 resources.OES_standard_derivatives = 2310 features().oes_standard_derivatives ? 1 : 0; 2311 resources.ARB_texture_rectangle = 2312 features().arb_texture_rectangle ? 1 : 0; 2313 resources.OES_EGL_image_external = 2314 features().oes_egl_image_external ? 1 : 0; 2315 } 2316 2317 ShShaderSpec shader_spec = force_webgl_glsl_validation_ || 2318 features().chromium_webglsl ? SH_WEBGL_SPEC : SH_GLES2_SPEC; 2319 ShaderTranslatorInterface::GlslImplementationType implementation_type = 2320 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ? 2321 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl; 2322 ShaderTranslatorInterface::GlslBuiltInFunctionBehavior function_behavior = 2323 workarounds().needs_glsl_built_in_function_emulation ? 2324 ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated : 2325 ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal; 2326 2327 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance(); 2328 vertex_translator_ = cache->GetTranslator( 2329 SH_VERTEX_SHADER, shader_spec, &resources, 2330 implementation_type, function_behavior); 2331 if (!vertex_translator_.get()) { 2332 LOG(ERROR) << "Could not initialize vertex shader translator."; 2333 Destroy(true); 2334 return false; 2335 } 2336 2337 fragment_translator_ = cache->GetTranslator( 2338 SH_FRAGMENT_SHADER, shader_spec, &resources, 2339 implementation_type, function_behavior); 2340 if (!fragment_translator_.get()) { 2341 LOG(ERROR) << "Could not initialize fragment shader translator."; 2342 Destroy(true); 2343 return false; 2344 } 2345 return true; 2346} 2347 2348bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) { 2349 for (GLsizei ii = 0; ii < n; ++ii) { 2350 if (GetBufferInfo(client_ids[ii])) { 2351 return false; 2352 } 2353 } 2354 scoped_array<GLuint> service_ids(new GLuint[n]); 2355 glGenBuffersARB(n, service_ids.get()); 2356 for (GLsizei ii = 0; ii < n; ++ii) { 2357 CreateBufferInfo(client_ids[ii], service_ids[ii]); 2358 } 2359 return true; 2360} 2361 2362bool GLES2DecoderImpl::GenFramebuffersHelper( 2363 GLsizei n, const GLuint* client_ids) { 2364 for (GLsizei ii = 0; ii < n; ++ii) { 2365 if (GetFramebufferInfo(client_ids[ii])) { 2366 return false; 2367 } 2368 } 2369 scoped_array<GLuint> service_ids(new GLuint[n]); 2370 glGenFramebuffersEXT(n, service_ids.get()); 2371 for (GLsizei ii = 0; ii < n; ++ii) { 2372 CreateFramebufferInfo(client_ids[ii], service_ids[ii]); 2373 } 2374 return true; 2375} 2376 2377bool GLES2DecoderImpl::GenRenderbuffersHelper( 2378 GLsizei n, const GLuint* client_ids) { 2379 for (GLsizei ii = 0; ii < n; ++ii) { 2380 if (GetRenderbufferInfo(client_ids[ii])) { 2381 return false; 2382 } 2383 } 2384 scoped_array<GLuint> service_ids(new GLuint[n]); 2385 glGenRenderbuffersEXT(n, service_ids.get()); 2386 for (GLsizei ii = 0; ii < n; ++ii) { 2387 CreateRenderbufferInfo(client_ids[ii], service_ids[ii]); 2388 } 2389 return true; 2390} 2391 2392bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) { 2393 for (GLsizei ii = 0; ii < n; ++ii) { 2394 if (GetTextureInfo(client_ids[ii])) { 2395 return false; 2396 } 2397 } 2398 scoped_array<GLuint> service_ids(new GLuint[n]); 2399 glGenTextures(n, service_ids.get()); 2400 for (GLsizei ii = 0; ii < n; ++ii) { 2401 CreateTextureInfo(client_ids[ii], service_ids[ii]); 2402 } 2403 return true; 2404} 2405 2406void GLES2DecoderImpl::DeleteBuffersHelper( 2407 GLsizei n, const GLuint* client_ids) { 2408 for (GLsizei ii = 0; ii < n; ++ii) { 2409 BufferManager::BufferInfo* buffer = GetBufferInfo(client_ids[ii]); 2410 if (buffer && !buffer->IsDeleted()) { 2411 state_.vertex_attrib_manager->Unbind(buffer); 2412 if (state_.bound_array_buffer == buffer) { 2413 state_.bound_array_buffer = NULL; 2414 } 2415 RemoveBufferInfo(client_ids[ii]); 2416 } 2417 } 2418} 2419 2420void GLES2DecoderImpl::DeleteFramebuffersHelper( 2421 GLsizei n, const GLuint* client_ids) { 2422 bool supports_separate_framebuffer_binds = 2423 features().chromium_framebuffer_multisample; 2424 2425 for (GLsizei ii = 0; ii < n; ++ii) { 2426 FramebufferManager::FramebufferInfo* framebuffer = 2427 GetFramebufferInfo(client_ids[ii]); 2428 if (framebuffer && !framebuffer->IsDeleted()) { 2429 if (framebuffer == state_.bound_draw_framebuffer) { 2430 state_.bound_draw_framebuffer = NULL; 2431 clear_state_dirty_ = true; 2432 GLenum target = supports_separate_framebuffer_binds ? 2433 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; 2434 glBindFramebufferEXT(target, GetBackbufferServiceId()); 2435 } 2436 if (framebuffer == state_.bound_read_framebuffer) { 2437 state_.bound_read_framebuffer = NULL; 2438 GLenum target = supports_separate_framebuffer_binds ? 2439 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; 2440 glBindFramebufferEXT(target, GetBackbufferServiceId()); 2441 } 2442 RemoveFramebufferInfo(client_ids[ii]); 2443 } 2444 } 2445} 2446 2447void GLES2DecoderImpl::DeleteRenderbuffersHelper( 2448 GLsizei n, const GLuint* client_ids) { 2449 bool supports_separate_framebuffer_binds = 2450 features().chromium_framebuffer_multisample; 2451 for (GLsizei ii = 0; ii < n; ++ii) { 2452 RenderbufferManager::RenderbufferInfo* renderbuffer = 2453 GetRenderbufferInfo(client_ids[ii]); 2454 if (renderbuffer && !renderbuffer->IsDeleted()) { 2455 if (state_.bound_renderbuffer == renderbuffer) { 2456 state_.bound_renderbuffer = NULL; 2457 } 2458 // Unbind from current framebuffers. 2459 if (supports_separate_framebuffer_binds) { 2460 if (state_.bound_read_framebuffer) { 2461 state_.bound_read_framebuffer->UnbindRenderbuffer( 2462 GL_READ_FRAMEBUFFER_EXT, renderbuffer); 2463 } 2464 if (state_.bound_draw_framebuffer) { 2465 state_.bound_draw_framebuffer->UnbindRenderbuffer( 2466 GL_DRAW_FRAMEBUFFER_EXT, renderbuffer); 2467 } 2468 } else { 2469 if (state_.bound_draw_framebuffer) { 2470 state_.bound_draw_framebuffer->UnbindRenderbuffer( 2471 GL_FRAMEBUFFER, renderbuffer); 2472 } 2473 } 2474 clear_state_dirty_ = true; 2475 RemoveRenderbufferInfo(client_ids[ii]); 2476 } 2477 } 2478} 2479 2480void GLES2DecoderImpl::DeleteTexturesHelper( 2481 GLsizei n, const GLuint* client_ids) { 2482 bool supports_separate_framebuffer_binds = 2483 features().chromium_framebuffer_multisample; 2484 for (GLsizei ii = 0; ii < n; ++ii) { 2485 TextureManager::TextureInfo* texture = GetTextureInfo(client_ids[ii]); 2486 if (texture && !texture->IsDeleted()) { 2487 if (texture->IsAttachedToFramebuffer()) { 2488 clear_state_dirty_ = true; 2489 } 2490 // Unbind texture from texture units. 2491 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) { 2492 state_.texture_units[jj].Unbind(texture); 2493 } 2494 // Unbind from current framebuffers. 2495 if (supports_separate_framebuffer_binds) { 2496 if (state_.bound_read_framebuffer) { 2497 state_.bound_read_framebuffer->UnbindTexture( 2498 GL_READ_FRAMEBUFFER_EXT, texture); 2499 } 2500 if (state_.bound_draw_framebuffer) { 2501 state_.bound_draw_framebuffer->UnbindTexture( 2502 GL_DRAW_FRAMEBUFFER_EXT, texture); 2503 } 2504 } else { 2505 if (state_.bound_draw_framebuffer) { 2506 state_.bound_draw_framebuffer->UnbindTexture(GL_FRAMEBUFFER, texture); 2507 } 2508 } 2509 GLuint service_id = texture->service_id(); 2510 if (texture->IsStreamTexture() && stream_texture_manager_) { 2511 stream_texture_manager_->DestroyStreamTexture(service_id); 2512 } 2513#if defined(OS_MACOSX) 2514 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) { 2515 ReleaseIOSurfaceForTexture(service_id); 2516 } 2517#endif 2518 RemoveTextureInfo(client_ids[ii]); 2519 } 2520 } 2521} 2522 2523// } // anonymous namespace 2524 2525bool GLES2DecoderImpl::MakeCurrent() { 2526 if (!context_.get() || !context_->MakeCurrent(surface_.get())) 2527 return false; 2528 2529 if (WasContextLost()) { 2530 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent."; 2531 return false; 2532 } 2533 2534 return true; 2535} 2536 2537void GLES2DecoderImpl::ReleaseCurrent() { 2538 if (context_.get()) 2539 context_->ReleaseCurrent(surface_.get()); 2540} 2541 2542void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() { 2543 RenderbufferManager::RenderbufferInfo* renderbuffer = 2544 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 2545 glBindRenderbufferEXT( 2546 GL_RENDERBUFFER, renderbuffer ? renderbuffer->service_id() : 0); 2547} 2548 2549static void RebindCurrentFramebuffer( 2550 GLenum target, 2551 FramebufferManager::FramebufferInfo* info, 2552 GLuint back_buffer_service_id) { 2553 GLuint framebuffer_id = info ? info->service_id() : 0; 2554 2555 if (framebuffer_id == 0) { 2556 framebuffer_id = back_buffer_service_id; 2557 } 2558 2559 glBindFramebufferEXT(target, framebuffer_id); 2560} 2561 2562void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() { 2563 clear_state_dirty_ = true; 2564 2565 if (!features().chromium_framebuffer_multisample) { 2566 RebindCurrentFramebuffer( 2567 GL_FRAMEBUFFER, 2568 state_.bound_draw_framebuffer.get(), 2569 GetBackbufferServiceId()); 2570 } else { 2571 RebindCurrentFramebuffer( 2572 GL_READ_FRAMEBUFFER_EXT, 2573 state_.bound_read_framebuffer.get(), 2574 GetBackbufferServiceId()); 2575 RebindCurrentFramebuffer( 2576 GL_DRAW_FRAMEBUFFER_EXT, 2577 state_.bound_draw_framebuffer.get(), 2578 GetBackbufferServiceId()); 2579 } 2580} 2581 2582void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() { 2583 TextureUnit& info = state_.texture_units[0]; 2584 GLuint last_id; 2585 if (info.bound_texture_2d) { 2586 last_id = info.bound_texture_2d->service_id(); 2587 } else { 2588 last_id = 0; 2589 } 2590 2591 glBindTexture(GL_TEXTURE_2D, last_id); 2592 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit); 2593} 2594 2595bool GLES2DecoderImpl::CheckFramebufferValid( 2596 FramebufferManager::FramebufferInfo* framebuffer, 2597 GLenum target, const char* func_name) { 2598 if (!framebuffer) { 2599 return true; 2600 } 2601 2602 if (framebuffer_manager()->IsComplete(framebuffer)) { 2603 return true; 2604 } 2605 2606 GLenum completeness = framebuffer->IsPossiblyComplete(); 2607 if (completeness != GL_FRAMEBUFFER_COMPLETE) { 2608 SetGLError( 2609 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete"); 2610 return false; 2611 } 2612 2613 // Are all the attachments cleared? 2614 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() || 2615 texture_manager()->HaveUnclearedMips()) { 2616 if (!framebuffer->IsCleared()) { 2617 // Can we clear them? 2618 if (framebuffer->GetStatus(texture_manager(), target) != 2619 GL_FRAMEBUFFER_COMPLETE) { 2620 SetGLError( 2621 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, 2622 "framebuffer incomplete (clear)"); 2623 return false; 2624 } 2625 ClearUnclearedAttachments(target, framebuffer); 2626 } 2627 } 2628 2629 if (!framebuffer_manager()->IsComplete(framebuffer)) { 2630 if (framebuffer->GetStatus(texture_manager(), target) != 2631 GL_FRAMEBUFFER_COMPLETE) { 2632 SetGLError( 2633 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, 2634 "framebuffer incomplete (check)"); 2635 return false; 2636 } 2637 framebuffer_manager()->MarkAsComplete(framebuffer); 2638 } 2639 2640 // NOTE: At this point we don't know if the framebuffer is complete but 2641 // we DO know that everything that needs to be cleared has been cleared. 2642 return true; 2643} 2644 2645bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) { 2646 if (!features().chromium_framebuffer_multisample) { 2647 return CheckFramebufferValid( 2648 state_.bound_draw_framebuffer, GL_FRAMEBUFFER_EXT, func_name); 2649 } 2650 return CheckFramebufferValid( 2651 state_.bound_draw_framebuffer, 2652 GL_DRAW_FRAMEBUFFER_EXT, func_name) && 2653 CheckFramebufferValid( 2654 state_.bound_read_framebuffer, 2655 GL_READ_FRAMEBUFFER_EXT, func_name); 2656} 2657 2658gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() { 2659 FramebufferManager::FramebufferInfo* framebuffer = 2660 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); 2661 if (framebuffer != NULL) { 2662 const FramebufferManager::FramebufferInfo::Attachment* attachment = 2663 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0); 2664 if (attachment) { 2665 return gfx::Size(attachment->width(), attachment->height()); 2666 } 2667 return gfx::Size(0, 0); 2668 } else if (offscreen_target_frame_buffer_.get()) { 2669 return offscreen_size_; 2670 } else { 2671 return surface_->GetSize(); 2672 } 2673} 2674 2675GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() { 2676 FramebufferManager::FramebufferInfo* framebuffer = 2677 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); 2678 if (framebuffer != NULL) { 2679 return framebuffer->GetColorAttachmentFormat(); 2680 } else if (offscreen_target_frame_buffer_.get()) { 2681 return offscreen_target_color_format_; 2682 } else { 2683 return back_buffer_color_format_; 2684 } 2685} 2686 2687GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() { 2688 FramebufferManager::FramebufferInfo* framebuffer = 2689 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 2690 if (framebuffer != NULL) { 2691 return framebuffer->GetColorAttachmentFormat(); 2692 } else if (offscreen_target_frame_buffer_.get()) { 2693 return offscreen_target_color_format_; 2694 } else { 2695 return back_buffer_color_format_; 2696 } 2697} 2698 2699void GLES2DecoderImpl::UpdateParentTextureInfo() { 2700 if (parent_) { 2701 // Update the info about the offscreen saved color texture in the parent. 2702 // The reference to the parent is a weak pointer and will become null if the 2703 // parent is later destroyed. 2704 TextureManager* parent_texture_manager = parent_->texture_manager(); 2705 parent_texture_manager->SetLevelInfo( 2706 offscreen_saved_color_texture_info_, 2707 GL_TEXTURE_2D, 2708 0, // level 2709 GL_RGBA, 2710 offscreen_size_.width(), 2711 offscreen_size_.height(), 2712 1, // depth 2713 0, // border 2714 GL_RGBA, 2715 GL_UNSIGNED_BYTE, 2716 true); 2717 parent_texture_manager->SetParameter( 2718 offscreen_saved_color_texture_info_, 2719 GL_TEXTURE_MAG_FILTER, 2720 GL_NEAREST); 2721 parent_texture_manager->SetParameter( 2722 offscreen_saved_color_texture_info_, 2723 GL_TEXTURE_MIN_FILTER, 2724 GL_NEAREST); 2725 parent_texture_manager->SetParameter( 2726 offscreen_saved_color_texture_info_, 2727 GL_TEXTURE_WRAP_S, 2728 GL_CLAMP_TO_EDGE); 2729 parent_texture_manager->SetParameter( 2730 offscreen_saved_color_texture_info_, 2731 GL_TEXTURE_WRAP_T, 2732 GL_CLAMP_TO_EDGE); 2733 } else { 2734 offscreen_saved_color_texture_info_ = NULL; 2735 } 2736} 2737 2738void GLES2DecoderImpl::SetResizeCallback( 2739 const base::Callback<void(gfx::Size)>& callback) { 2740 resize_callback_ = callback; 2741} 2742 2743void GLES2DecoderImpl::SetMsgCallback(const MsgCallback& callback) { 2744 msg_callback_ = callback; 2745} 2746 2747void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) { 2748 stream_texture_manager_ = manager; 2749} 2750 2751bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, 2752 uint32* service_texture_id) { 2753 TextureManager::TextureInfo* texture = 2754 texture_manager()->GetTextureInfo(client_texture_id); 2755 if (texture) { 2756 *service_texture_id = texture->service_id(); 2757 return true; 2758 } 2759 return false; 2760} 2761 2762uint32 GLES2DecoderImpl::GetTextureUploadCount() { 2763 return texture_upload_count_; 2764} 2765 2766base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() { 2767 return total_texture_upload_time_; 2768} 2769 2770base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() { 2771 return total_processing_commands_time_; 2772} 2773 2774void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) { 2775 total_processing_commands_time_ += time; 2776} 2777 2778void GLES2DecoderImpl::Destroy(bool have_context) { 2779 DCHECK(!have_context || context_->IsCurrent(NULL)); 2780 2781 ChildList children = children_; 2782 for (ChildList::iterator it = children.begin(); it != children.end(); ++it) 2783 (*it)->SetParent(NULL, 0); 2784 DCHECK(children_.empty()); 2785 SetParent(NULL, 0); 2786 2787 // Unbind everything. 2788 state_.vertex_attrib_manager = NULL; 2789 default_vertex_attrib_manager_ = NULL; 2790 state_.texture_units.clear(); 2791 state_.bound_array_buffer = NULL; 2792 state_.current_query = NULL; 2793 state_.current_program = NULL; 2794 state_.bound_read_framebuffer = NULL; 2795 state_.bound_draw_framebuffer = NULL; 2796 state_.bound_renderbuffer = NULL; 2797 2798 if (have_context) { 2799 if (copy_texture_CHROMIUM_.get()) { 2800 copy_texture_CHROMIUM_->Destroy(); 2801 copy_texture_CHROMIUM_.reset(); 2802 } 2803 2804 if (state_.current_program) { 2805 program_manager()->UnuseProgram(shader_manager(), state_.current_program); 2806 state_.current_program = NULL; 2807 } 2808 2809 if (attrib_0_buffer_id_) { 2810 glDeleteBuffersARB(1, &attrib_0_buffer_id_); 2811 } 2812 if (fixed_attrib_buffer_id_) { 2813 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_); 2814 } 2815 2816 if (offscreen_target_frame_buffer_.get()) 2817 offscreen_target_frame_buffer_->Destroy(); 2818 if (offscreen_target_color_texture_.get()) 2819 offscreen_target_color_texture_->Destroy(); 2820 if (offscreen_target_color_render_buffer_.get()) 2821 offscreen_target_color_render_buffer_->Destroy(); 2822 if (offscreen_target_depth_render_buffer_.get()) 2823 offscreen_target_depth_render_buffer_->Destroy(); 2824 if (offscreen_target_stencil_render_buffer_.get()) 2825 offscreen_target_stencil_render_buffer_->Destroy(); 2826 if (offscreen_saved_frame_buffer_.get()) 2827 offscreen_saved_frame_buffer_->Destroy(); 2828 if (offscreen_saved_color_texture_.get()) 2829 offscreen_saved_color_texture_->Destroy(); 2830 if (offscreen_resolved_frame_buffer_.get()) 2831 offscreen_resolved_frame_buffer_->Destroy(); 2832 if (offscreen_resolved_color_texture_.get()) 2833 offscreen_resolved_color_texture_->Destroy(); 2834 } else { 2835 if (offscreen_target_frame_buffer_.get()) 2836 offscreen_target_frame_buffer_->Invalidate(); 2837 if (offscreen_target_color_texture_.get()) 2838 offscreen_target_color_texture_->Invalidate(); 2839 if (offscreen_target_color_render_buffer_.get()) 2840 offscreen_target_color_render_buffer_->Invalidate(); 2841 if (offscreen_target_depth_render_buffer_.get()) 2842 offscreen_target_depth_render_buffer_->Invalidate(); 2843 if (offscreen_target_stencil_render_buffer_.get()) 2844 offscreen_target_stencil_render_buffer_->Invalidate(); 2845 if (offscreen_saved_frame_buffer_.get()) 2846 offscreen_saved_frame_buffer_->Invalidate(); 2847 if (offscreen_saved_color_texture_.get()) 2848 offscreen_saved_color_texture_->Invalidate(); 2849 if (offscreen_resolved_frame_buffer_.get()) 2850 offscreen_resolved_frame_buffer_->Invalidate(); 2851 if (offscreen_resolved_color_texture_.get()) 2852 offscreen_resolved_color_texture_->Invalidate(); 2853 } 2854 copy_texture_CHROMIUM_.reset(); 2855 2856 if (query_manager_.get()) { 2857 query_manager_->Destroy(have_context); 2858 query_manager_.reset(); 2859 } 2860 2861 if (vertex_array_manager_ .get()) { 2862 vertex_array_manager_->Destroy(have_context); 2863 vertex_array_manager_.reset(); 2864 } 2865 2866 if (group_) { 2867 group_->Destroy(have_context); 2868 group_ = NULL; 2869 } 2870 2871 if (context_.get()) { 2872 context_->ReleaseCurrent(NULL); 2873 context_ = NULL; 2874 } 2875 2876 offscreen_target_frame_buffer_.reset(); 2877 offscreen_target_color_texture_.reset(); 2878 offscreen_target_color_render_buffer_.reset(); 2879 offscreen_target_depth_render_buffer_.reset(); 2880 offscreen_target_stencil_render_buffer_.reset(); 2881 offscreen_saved_frame_buffer_.reset(); 2882 offscreen_saved_color_texture_.reset(); 2883 offscreen_resolved_frame_buffer_.reset(); 2884 offscreen_resolved_color_texture_.reset(); 2885 2886#if defined(OS_MACOSX) 2887 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin(); 2888 it != texture_to_io_surface_map_.end(); ++it) { 2889 CFRelease(it->second); 2890 } 2891 texture_to_io_surface_map_.clear(); 2892#endif 2893} 2894 2895void GLES2DecoderImpl::SetSurface( 2896 const scoped_refptr<gfx::GLSurface>& surface) { 2897 DCHECK(context_->IsCurrent(NULL)); 2898 DCHECK(surface_.get()); 2899 surface_ = surface; 2900 RestoreCurrentFramebufferBindings(); 2901} 2902 2903bool GLES2DecoderImpl::SetParent(GLES2Decoder* new_parent, 2904 uint32 new_parent_texture_id) { 2905 if (!offscreen_saved_color_texture_.get()) 2906 return false; 2907 2908 // Remove the saved frame buffer mapping from the parent decoder. The 2909 // parent pointer is a weak pointer so it will be null if the parent has 2910 // already been destroyed. 2911 if (parent_) { 2912 ChildList::iterator it = std::find( 2913 parent_->children_.begin(), 2914 parent_->children_.end(), 2915 this); 2916 DCHECK(it != parent_->children_.end()); 2917 parent_->children_.erase(it); 2918 // First check the texture has been mapped into the parent. This might not 2919 // be the case if initialization failed midway through. 2920 GLuint service_id = offscreen_saved_color_texture_->id(); 2921 GLuint client_id = 0; 2922 if (parent_->texture_manager()->GetClientId(service_id, &client_id)) { 2923 parent_->texture_manager()->RemoveTextureInfo(client_id); 2924 } 2925 } 2926 2927 GLES2DecoderImpl* new_parent_impl = static_cast<GLES2DecoderImpl*>( 2928 new_parent); 2929 if (new_parent_impl) { 2930#ifndef NDEBUG 2931 ChildList::iterator it = std::find( 2932 new_parent_impl->children_.begin(), 2933 new_parent_impl->children_.end(), 2934 this); 2935 DCHECK(it == new_parent_impl->children_.end()); 2936#endif 2937 new_parent_impl->children_.push_back(this); 2938 // Map the ID of the saved offscreen texture into the parent so that 2939 // it can reference it. 2940 GLuint service_id = offscreen_saved_color_texture_->id(); 2941 2942 // Replace texture info when ID is already in use by parent. 2943 if (new_parent_impl->texture_manager()->GetTextureInfo( 2944 new_parent_texture_id)) 2945 new_parent_impl->texture_manager()->RemoveTextureInfo( 2946 new_parent_texture_id); 2947 2948 offscreen_saved_color_texture_info_ = 2949 new_parent_impl->CreateTextureInfo(new_parent_texture_id, service_id); 2950 offscreen_saved_color_texture_info_->SetNotOwned(); 2951 new_parent_impl->texture_manager()-> 2952 SetInfoTarget(offscreen_saved_color_texture_info_, GL_TEXTURE_2D); 2953 2954 parent_ = new_parent_impl->AsWeakPtr(); 2955 2956 UpdateParentTextureInfo(); 2957 } else { 2958 parent_.reset(); 2959 offscreen_saved_color_texture_info_ = NULL; 2960 } 2961 2962 return true; 2963} 2964 2965size_t GLES2DecoderImpl::GetBackbufferMemoryTotal() { 2966 size_t total = 0; 2967 if (offscreen_target_frame_buffer_.get()) { 2968 if (offscreen_target_color_texture_.get()) { 2969 total += offscreen_target_color_texture_->estimated_size(); 2970 } 2971 if (offscreen_target_color_render_buffer_.get()) { 2972 total += offscreen_target_color_render_buffer_->estimated_size(); 2973 } 2974 if (offscreen_target_depth_render_buffer_.get()) { 2975 total += offscreen_target_depth_render_buffer_->estimated_size(); 2976 } 2977 if (offscreen_target_stencil_render_buffer_.get()) { 2978 total += offscreen_target_stencil_render_buffer_->estimated_size(); 2979 } 2980 if (offscreen_saved_color_texture_.get()) { 2981 total += offscreen_saved_color_texture_->estimated_size(); 2982 } 2983 if (offscreen_resolved_color_texture_.get()) { 2984 total += offscreen_resolved_color_texture_->estimated_size(); 2985 } 2986 } else { 2987 gfx::Size size = surface_->GetSize(); 2988 total += size.width() * size.height() * 2989 GLES2Util::RenderbufferBytesPerPixel(back_buffer_color_format_); 2990 } 2991 return total; 2992} 2993 2994bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) { 2995 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); 2996 if (!is_offscreen) { 2997 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called " 2998 << " with an onscreen framebuffer."; 2999 return false; 3000 } 3001 3002 if (offscreen_size_ == size) 3003 return true; 3004 3005 offscreen_size_ = size; 3006 int w = offscreen_size_.width(); 3007 int h = offscreen_size_.height(); 3008 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) { 3009 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3010 << "to allocate storage due to excessive dimensions."; 3011 return false; 3012 } 3013 3014 // Reallocate the offscreen target buffers. 3015 DCHECK(offscreen_target_color_format_); 3016 if (IsOffscreenBufferMultisampled()) { 3017 if (!offscreen_target_color_render_buffer_->AllocateStorage( 3018 offscreen_size_, offscreen_target_color_format_, 3019 offscreen_target_samples_)) { 3020 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3021 << "to allocate storage for offscreen target color buffer."; 3022 return false; 3023 } 3024 } else { 3025 if (!offscreen_target_color_texture_->AllocateStorage( 3026 offscreen_size_, offscreen_target_color_format_)) { 3027 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3028 << "to allocate storage for offscreen target color texture."; 3029 return false; 3030 } 3031 } 3032 if (offscreen_target_depth_format_ && 3033 !offscreen_target_depth_render_buffer_->AllocateStorage( 3034 offscreen_size_, offscreen_target_depth_format_, 3035 offscreen_target_samples_)) { 3036 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3037 << "to allocate storage for offscreen target depth buffer."; 3038 return false; 3039 } 3040 if (offscreen_target_stencil_format_ && 3041 !offscreen_target_stencil_render_buffer_->AllocateStorage( 3042 offscreen_size_, offscreen_target_stencil_format_, 3043 offscreen_target_samples_)) { 3044 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3045 << "to allocate storage for offscreen target stencil buffer."; 3046 return false; 3047 } 3048 3049 // Attach the offscreen target buffers to the target frame buffer. 3050 if (IsOffscreenBufferMultisampled()) { 3051 offscreen_target_frame_buffer_->AttachRenderBuffer( 3052 GL_COLOR_ATTACHMENT0, 3053 offscreen_target_color_render_buffer_.get()); 3054 } else { 3055 offscreen_target_frame_buffer_->AttachRenderTexture( 3056 offscreen_target_color_texture_.get()); 3057 } 3058 if (offscreen_target_depth_format_) { 3059 offscreen_target_frame_buffer_->AttachRenderBuffer( 3060 GL_DEPTH_ATTACHMENT, 3061 offscreen_target_depth_render_buffer_.get()); 3062 } 3063 const bool packed_depth_stencil = 3064 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8; 3065 if (packed_depth_stencil) { 3066 offscreen_target_frame_buffer_->AttachRenderBuffer( 3067 GL_STENCIL_ATTACHMENT, 3068 offscreen_target_depth_render_buffer_.get()); 3069 } else if (offscreen_target_stencil_format_) { 3070 offscreen_target_frame_buffer_->AttachRenderBuffer( 3071 GL_STENCIL_ATTACHMENT, 3072 offscreen_target_stencil_render_buffer_.get()); 3073 } 3074 3075 if (offscreen_target_frame_buffer_->CheckStatus() != 3076 GL_FRAMEBUFFER_COMPLETE) { 3077 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 3078 << "because offscreen FBO was incomplete."; 3079 return false; 3080 } 3081 3082 // Clear the target frame buffer. 3083 { 3084 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id()); 3085 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat( 3086 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1); 3087 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 3088 glClearStencil(0); 3089 glStencilMaskSeparate(GL_FRONT, -1); 3090 glStencilMaskSeparate(GL_BACK, -1); 3091 glClearDepth(0); 3092 glDepthMask(GL_TRUE); 3093 glDisable(GL_SCISSOR_TEST); 3094 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 3095 RestoreClearState(); 3096 } 3097 3098 // Destroy the offscreen resolved framebuffers. 3099 if (offscreen_resolved_frame_buffer_.get()) 3100 offscreen_resolved_frame_buffer_->Destroy(); 3101 if (offscreen_resolved_color_texture_.get()) 3102 offscreen_resolved_color_texture_->Destroy(); 3103 offscreen_resolved_color_texture_.reset(); 3104 offscreen_resolved_frame_buffer_.reset(); 3105 3106 return true; 3107} 3108 3109error::Error GLES2DecoderImpl::HandleResizeCHROMIUM( 3110 uint32 immediate_data_size, const gles2::ResizeCHROMIUM& c) { 3111 if (ShouldDeferDraws()) 3112 return error::kDeferCommandUntilLater; 3113 3114 GLuint width = static_cast<GLuint>(c.width); 3115 GLuint height = static_cast<GLuint>(c.height); 3116 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height); 3117#if defined(OS_POSIX) && !defined(OS_MACOSX) && \ 3118 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) 3119 // Make sure that we are done drawing to the back buffer before resizing. 3120 glFinish(); 3121#endif 3122 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); 3123 if (is_offscreen) { 3124 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) { 3125 LOG(ERROR) << "GLES2DecoderImpl: Context lost because " 3126 << "ResizeOffscreenFrameBuffer failed."; 3127 return error::kLostContext; 3128 } 3129 } 3130 3131 if (!resize_callback_.is_null()) { 3132 resize_callback_.Run(gfx::Size(width, height)); 3133 DCHECK(context_->IsCurrent(surface_.get())); 3134 if (!context_->IsCurrent(surface_.get())) { 3135 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer " 3136 << "current after resize callback."; 3137 return error::kLostContext; 3138 } 3139 } 3140 3141 return error::kNoError; 3142} 3143 3144const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const { 3145 if (command_id > kStartPoint && command_id < kNumCommands) { 3146 return gles2::GetCommandName(static_cast<CommandId>(command_id)); 3147 } 3148 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id)); 3149} 3150 3151// Decode command with its arguments, and call the corresponding GL function. 3152// Note: args is a pointer to the command buffer. As such, it could be changed 3153// by a (malicious) client at any time, so if validation has to happen, it 3154// should operate on a copy of them. 3155error::Error GLES2DecoderImpl::DoCommand( 3156 unsigned int command, 3157 unsigned int arg_count, 3158 const void* cmd_data) { 3159 error::Error result = error::kNoError; 3160 if (log_commands()) { 3161 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried 3162 // LOG(INFO), tried VLOG(1), no luck. 3163 LOG(ERROR) << "[" << GetLogPrefix() << "]" << "cmd: " 3164 << GetCommandName(command); 3165 } 3166 unsigned int command_index = command - kStartPoint - 1; 3167 if (command_index < arraysize(g_command_info)) { 3168 const CommandInfo& info = g_command_info[command_index]; 3169 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count); 3170 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || 3171 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { 3172 uint32 immediate_data_size = 3173 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT 3174 switch (command) { 3175 #define GLES2_CMD_OP(name) \ 3176 case name::kCmdId: \ 3177 result = Handle ## name( \ 3178 immediate_data_size, \ 3179 *static_cast<const name*>(cmd_data)); \ 3180 break; \ 3181 3182 GLES2_COMMAND_LIST(GLES2_CMD_OP) 3183 #undef GLES2_CMD_OP 3184 } 3185 if (debug()) { 3186 GLenum error; 3187 while ((error = glGetError()) != GL_NO_ERROR) { 3188 LOG(ERROR) << "[" << GetLogPrefix() << "] " 3189 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : " 3190 << GetCommandName(command); 3191 SetGLError(error, "DoCommand", "GL error from driver"); 3192 } 3193 } 3194 } else { 3195 result = error::kInvalidArguments; 3196 } 3197 } else { 3198 result = DoCommonCommand(command, arg_count, cmd_data); 3199 } 3200 if (result == error::kNoError && current_decoder_error_ != error::kNoError) { 3201 result = current_decoder_error_; 3202 current_decoder_error_ = error::kNoError; 3203 } 3204 return result; 3205} 3206 3207void GLES2DecoderImpl::RemoveBufferInfo(GLuint client_id) { 3208 buffer_manager()->RemoveBufferInfo(client_id); 3209} 3210 3211bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) { 3212 if (GetProgramInfo(client_id)) { 3213 return false; 3214 } 3215 GLuint service_id = glCreateProgram(); 3216 if (service_id != 0) { 3217 CreateProgramInfo(client_id, service_id); 3218 } 3219 return true; 3220} 3221 3222bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) { 3223 if (GetShaderInfo(client_id)) { 3224 return false; 3225 } 3226 GLuint service_id = glCreateShader(type); 3227 if (service_id != 0) { 3228 CreateShaderInfo(client_id, service_id, type); 3229 } 3230 return true; 3231} 3232 3233void GLES2DecoderImpl::DoFinish() { 3234 glFinish(); 3235 ProcessPendingQueries(); 3236} 3237 3238void GLES2DecoderImpl::DoFlush() { 3239 glFlush(); 3240 ProcessPendingQueries(); 3241} 3242 3243void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) { 3244 GLuint texture_index = texture_unit - GL_TEXTURE0; 3245 if (texture_index >= state_.texture_units.size()) { 3246 SetGLErrorInvalidEnum( 3247 "glActiveTexture", texture_unit, "texture_unit"); 3248 return; 3249 } 3250 state_.active_texture_unit = texture_index; 3251 glActiveTexture(texture_unit); 3252} 3253 3254void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) { 3255 BufferManager::BufferInfo* info = NULL; 3256 GLuint service_id = 0; 3257 if (client_id != 0) { 3258 info = GetBufferInfo(client_id); 3259 if (!info) { 3260 if (!group_->bind_generates_resource()) { 3261 LOG(ERROR) << "glBindBuffer: id not generated by glGenBuffers"; 3262 current_decoder_error_ = error::kGenericError; 3263 return; 3264 } 3265 3266 // It's a new id so make a buffer info for it. 3267 glGenBuffersARB(1, &service_id); 3268 CreateBufferInfo(client_id, service_id); 3269 info = GetBufferInfo(client_id); 3270 IdAllocatorInterface* id_allocator = 3271 group_->GetIdAllocator(id_namespaces::kBuffers); 3272 id_allocator->MarkAsUsed(client_id); 3273 } 3274 } 3275 if (info) { 3276 if (!buffer_manager()->SetTarget(info, target)) { 3277 SetGLError(GL_INVALID_OPERATION, 3278 "glBindBuffer", "buffer bound to more than 1 target"); 3279 return; 3280 } 3281 service_id = info->service_id(); 3282 } 3283 switch (target) { 3284 case GL_ARRAY_BUFFER: 3285 state_.bound_array_buffer = info; 3286 break; 3287 case GL_ELEMENT_ARRAY_BUFFER: 3288 state_.vertex_attrib_manager->SetElementArrayBuffer(info); 3289 break; 3290 default: 3291 NOTREACHED(); // Validation should prevent us getting here. 3292 break; 3293 } 3294 glBindBuffer(target, service_id); 3295} 3296 3297bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha() { 3298 return (GLES2Util::GetChannelsForFormat( 3299 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0; 3300} 3301 3302bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() { 3303 FramebufferManager::FramebufferInfo* framebuffer = 3304 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 3305 if (framebuffer) { 3306 return framebuffer->HasDepthAttachment(); 3307 } 3308 if (offscreen_target_frame_buffer_.get()) { 3309 return offscreen_target_depth_format_ != 0; 3310 } 3311 return back_buffer_has_depth_; 3312} 3313 3314bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() { 3315 FramebufferManager::FramebufferInfo* framebuffer = 3316 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 3317 if (framebuffer) { 3318 return framebuffer->HasStencilAttachment(); 3319 } 3320 if (offscreen_target_frame_buffer_.get()) { 3321 return offscreen_target_stencil_format_ != 0 || 3322 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8; 3323 } 3324 return back_buffer_has_stencil_; 3325} 3326 3327void GLES2DecoderImpl::ApplyDirtyState() { 3328 if (clear_state_dirty_) { 3329 glColorMask( 3330 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue, 3331 state_.color_mask_alpha && 3332 BoundFramebufferHasColorAttachmentWithAlpha()); 3333 bool have_depth = BoundFramebufferHasDepthAttachment(); 3334 glDepthMask(state_.depth_mask && have_depth); 3335 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth); 3336 bool have_stencil = BoundFramebufferHasStencilAttachment(); 3337 glStencilMaskSeparate( 3338 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0); 3339 glStencilMaskSeparate( 3340 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0); 3341 EnableDisable( 3342 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil); 3343 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face); 3344 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test); 3345 EnableDisable(GL_BLEND, state_.enable_flags.blend); 3346 clear_state_dirty_ = false; 3347 } 3348} 3349 3350void GLES2DecoderImpl::BindAndApplyTextureParameters( 3351 TextureManager::TextureInfo* info) { 3352 glBindTexture(info->target(), info->service_id()); 3353 glTexParameteri(info->target(), GL_TEXTURE_MIN_FILTER, info->min_filter()); 3354 glTexParameteri(info->target(), GL_TEXTURE_MAG_FILTER, info->mag_filter()); 3355 glTexParameteri(info->target(), GL_TEXTURE_WRAP_S, info->wrap_s()); 3356 glTexParameteri(info->target(), GL_TEXTURE_WRAP_T, info->wrap_t()); 3357} 3358 3359GLuint GLES2DecoderImpl::GetBackbufferServiceId() const { 3360 return (offscreen_target_frame_buffer_.get()) ? 3361 offscreen_target_frame_buffer_->id() : 3362 (surface_ ? surface_->GetBackingFrameBufferObject() : 0); 3363} 3364 3365void GLES2DecoderImpl::RestoreState() const { 3366 state_.RestoreState(); 3367 3368 // TODO: Restore multisample bindings 3369 GLuint service_id = state_.bound_draw_framebuffer ? 3370 state_.bound_draw_framebuffer->service_id() : 3371 GetBackbufferServiceId(); 3372 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id); 3373} 3374 3375void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) { 3376 FramebufferManager::FramebufferInfo* info = NULL; 3377 GLuint service_id = 0; 3378 if (client_id != 0) { 3379 info = GetFramebufferInfo(client_id); 3380 if (!info) { 3381 if (!group_->bind_generates_resource()) { 3382 LOG(ERROR) 3383 << "glBindFramebuffer: id not generated by glGenFramebuffers"; 3384 current_decoder_error_ = error::kGenericError; 3385 return; 3386 } 3387 3388 // It's a new id so make a framebuffer info for it. 3389 glGenFramebuffersEXT(1, &service_id); 3390 CreateFramebufferInfo(client_id, service_id); 3391 info = GetFramebufferInfo(client_id); 3392 IdAllocatorInterface* id_allocator = 3393 group_->GetIdAllocator(id_namespaces::kFramebuffers); 3394 id_allocator->MarkAsUsed(client_id); 3395 } else { 3396 service_id = info->service_id(); 3397 } 3398 info->MarkAsValid(); 3399 } 3400 3401 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) { 3402 state_.bound_draw_framebuffer = info; 3403 } 3404 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) { 3405 state_.bound_read_framebuffer = info; 3406 } 3407 3408 clear_state_dirty_ = true; 3409 3410 // If we are rendering to the backbuffer get the FBO id for any simulated 3411 // backbuffer. 3412 if (info == NULL) { 3413 service_id = GetBackbufferServiceId(); 3414 } 3415 3416 glBindFramebufferEXT(target, service_id); 3417} 3418 3419void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) { 3420 RenderbufferManager::RenderbufferInfo* info = NULL; 3421 GLuint service_id = 0; 3422 if (client_id != 0) { 3423 info = GetRenderbufferInfo(client_id); 3424 if (!info) { 3425 if (!group_->bind_generates_resource()) { 3426 LOG(ERROR) 3427 << "glBindRenderbuffer: id not generated by glGenRenderbuffers"; 3428 current_decoder_error_ = error::kGenericError; 3429 return; 3430 } 3431 3432 // It's a new id so make a renderbuffer info for it. 3433 glGenRenderbuffersEXT(1, &service_id); 3434 CreateRenderbufferInfo(client_id, service_id); 3435 info = GetRenderbufferInfo(client_id); 3436 IdAllocatorInterface* id_allocator = 3437 group_->GetIdAllocator(id_namespaces::kRenderbuffers); 3438 id_allocator->MarkAsUsed(client_id); 3439 } else { 3440 service_id = info->service_id(); 3441 } 3442 info->MarkAsValid(); 3443 } 3444 state_.bound_renderbuffer = info; 3445 glBindRenderbufferEXT(target, service_id); 3446} 3447 3448void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) { 3449 TextureManager::TextureInfo* info = NULL; 3450 GLuint service_id = 0; 3451 if (client_id != 0) { 3452 info = GetTextureInfo(client_id); 3453 if (!info) { 3454 if (!group_->bind_generates_resource()) { 3455 LOG(ERROR) << "glBindTexture: id not generated by glGenTextures"; 3456 current_decoder_error_ = error::kGenericError; 3457 return; 3458 } 3459 3460 // It's a new id so make a texture info for it. 3461 glGenTextures(1, &service_id); 3462 DCHECK_NE(0u, service_id); 3463 CreateTextureInfo(client_id, service_id); 3464 info = GetTextureInfo(client_id); 3465 IdAllocatorInterface* id_allocator = 3466 group_->GetIdAllocator(id_namespaces::kTextures); 3467 id_allocator->MarkAsUsed(client_id); 3468 } 3469 } else { 3470 info = texture_manager()->GetDefaultTextureInfo(target); 3471 } 3472 3473 // Check the texture exists 3474 // Check that we are not trying to bind it to a different target. 3475 if (info->target() != 0 && info->target() != target) { 3476 SetGLError(GL_INVALID_OPERATION, 3477 "glBindTexture", "texture bound to more than 1 target."); 3478 return; 3479 } 3480 if (info->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) { 3481 SetGLError(GL_INVALID_OPERATION, 3482 "glBindTexture", "illegal target for stream texture."); 3483 return; 3484 } 3485 if (info->target() == 0) { 3486 texture_manager()->SetInfoTarget(info, target); 3487 } 3488 glBindTexture(target, info->service_id()); 3489 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 3490 unit.bind_target = target; 3491 switch (target) { 3492 case GL_TEXTURE_2D: 3493 unit.bound_texture_2d = info; 3494 break; 3495 case GL_TEXTURE_CUBE_MAP: 3496 unit.bound_texture_cube_map = info; 3497 break; 3498 case GL_TEXTURE_EXTERNAL_OES: 3499 unit.bound_texture_external_oes = info; 3500 if (info->IsStreamTexture()) { 3501 DCHECK(stream_texture_manager_); 3502 StreamTexture* stream_tex = 3503 stream_texture_manager_->LookupStreamTexture(info->service_id()); 3504 if (stream_tex) 3505 stream_tex->Update(); 3506 } 3507 break; 3508 case GL_TEXTURE_RECTANGLE_ARB: 3509 unit.bound_texture_rectangle_arb = info; 3510 break; 3511 default: 3512 NOTREACHED(); // Validation should prevent us getting here. 3513 break; 3514 } 3515} 3516 3517void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) { 3518 if (state_.vertex_attrib_manager->Enable(index, false)) { 3519 if (index != 0 || 3520 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { 3521 glDisableVertexAttribArray(index); 3522 } 3523 } else { 3524 SetGLError(GL_INVALID_VALUE, 3525 "glDisableVertexAttribArray", "index out of range"); 3526 } 3527} 3528 3529void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) { 3530 if (state_.vertex_attrib_manager->Enable(index, true)) { 3531 glEnableVertexAttribArray(index); 3532 } else { 3533 SetGLError(GL_INVALID_VALUE, 3534 "glEnableVertexAttribArray", "index out of range"); 3535 } 3536} 3537 3538void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) { 3539 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 3540 if (!info || 3541 !texture_manager()->CanGenerateMipmaps(info)) { 3542 SetGLError(GL_INVALID_OPERATION, 3543 "glGenerateMipmaps", "Can not generate mips"); 3544 return; 3545 } 3546 3547 if (!texture_manager()->ClearTextureLevel(this, info, target, 0)) { 3548 SetGLError(GL_OUT_OF_MEMORY, "glGenerateMipmaps", "dimensions too big"); 3549 return; 3550 } 3551 3552 CopyRealGLErrorsToWrapper(); 3553 // Workaround for Mac driver bug. In the large scheme of things setting 3554 // glTexParamter twice for glGenerateMipmap is probably not a lage performance 3555 // hit so there's probably no need to make this conditional. The bug appears 3556 // to be that if the filtering mode is set to something that doesn't require 3557 // mipmaps for rendering, or is never set to something other than the default, 3558 // then glGenerateMipmap misbehaves. 3559 if (workarounds().set_texture_filter_before_generating_mipmap) { 3560 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 3561 } 3562 glGenerateMipmapEXT(target); 3563 if (workarounds().set_texture_filter_before_generating_mipmap) { 3564 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, info->min_filter()); 3565 } 3566 GLenum error = PeekGLError(); 3567 if (error == GL_NO_ERROR) { 3568 texture_manager()->MarkMipmapsGenerated(info); 3569 } 3570} 3571 3572bool GLES2DecoderImpl::GetHelper( 3573 GLenum pname, GLint* params, GLsizei* num_written) { 3574 DCHECK(num_written); 3575 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 3576 switch (pname) { 3577 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 3578 *num_written = 1; 3579 if (params) { 3580 *params = GL_RGBA; // We don't support other formats. 3581 } 3582 return true; 3583 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 3584 *num_written = 1; 3585 if (params) { 3586 *params = GL_UNSIGNED_BYTE; // We don't support other types. 3587 } 3588 return true; 3589 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: 3590 *num_written = 1; 3591 if (params) { 3592 *params = group_->max_fragment_uniform_vectors(); 3593 } 3594 return true; 3595 case GL_MAX_VARYING_VECTORS: 3596 *num_written = 1; 3597 if (params) { 3598 *params = group_->max_varying_vectors(); 3599 } 3600 return true; 3601 case GL_MAX_VERTEX_UNIFORM_VECTORS: 3602 *num_written = 1; 3603 if (params) { 3604 *params = group_->max_vertex_uniform_vectors(); 3605 } 3606 return true; 3607 } 3608 } 3609 switch (pname) { 3610 case GL_MAX_VIEWPORT_DIMS: 3611 if (offscreen_target_frame_buffer_.get()) { 3612 *num_written = 2; 3613 if (params) { 3614 params[0] = renderbuffer_manager()->max_renderbuffer_size(); 3615 params[1] = renderbuffer_manager()->max_renderbuffer_size(); 3616 } 3617 return true; 3618 } 3619 return false; 3620 case GL_MAX_SAMPLES: 3621 *num_written = 1; 3622 if (params) { 3623 params[0] = renderbuffer_manager()->max_samples(); 3624 } 3625 return true; 3626 case GL_MAX_RENDERBUFFER_SIZE: 3627 *num_written = 1; 3628 if (params) { 3629 params[0] = renderbuffer_manager()->max_renderbuffer_size(); 3630 } 3631 return true; 3632 case GL_MAX_TEXTURE_SIZE: 3633 *num_written = 1; 3634 if (params) { 3635 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D); 3636 } 3637 return true; 3638 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: 3639 *num_written = 1; 3640 if (params) { 3641 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP); 3642 } 3643 return true; 3644 case GL_ALPHA_BITS: 3645 *num_written = 1; 3646 if (params) { 3647 GLint v = 0; 3648 glGetIntegerv(GL_ALPHA_BITS, &v); 3649 params[0] = BoundFramebufferHasColorAttachmentWithAlpha() ? v : 0; 3650 } 3651 return true; 3652 case GL_DEPTH_BITS: 3653 *num_written = 1; 3654 if (params) { 3655 GLint v = 0; 3656 glGetIntegerv(GL_DEPTH_BITS, &v); 3657 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0; 3658 } 3659 return true; 3660 case GL_STENCIL_BITS: 3661 *num_written = 1; 3662 if (params) { 3663 GLint v = 0; 3664 glGetIntegerv(GL_STENCIL_BITS, &v); 3665 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0; 3666 } 3667 return true; 3668 case GL_COMPRESSED_TEXTURE_FORMATS: 3669 *num_written = validators_->compressed_texture_format.GetValues().size(); 3670 if (params) { 3671 for (GLint ii = 0; ii < *num_written; ++ii) { 3672 params[ii] = validators_->compressed_texture_format.GetValues()[ii]; 3673 } 3674 } 3675 return true; 3676 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 3677 *num_written = 1; 3678 if (params) { 3679 *params = validators_->compressed_texture_format.GetValues().size(); 3680 } 3681 return true; 3682 case GL_NUM_SHADER_BINARY_FORMATS: 3683 *num_written = 1; 3684 if (params) { 3685 *params = validators_->shader_binary_format.GetValues().size(); 3686 } 3687 return true; 3688 case GL_SHADER_BINARY_FORMATS: 3689 *num_written = validators_->shader_binary_format.GetValues().size(); 3690 if (params) { 3691 for (GLint ii = 0; ii < *num_written; ++ii) { 3692 params[ii] = validators_->shader_binary_format.GetValues()[ii]; 3693 } 3694 } 3695 return true; 3696 case GL_SHADER_COMPILER: 3697 *num_written = 1; 3698 if (params) { 3699 *params = GL_TRUE; 3700 } 3701 return true; 3702 case GL_ARRAY_BUFFER_BINDING: 3703 *num_written = 1; 3704 if (params) { 3705 if (state_.bound_array_buffer) { 3706 GLuint client_id = 0; 3707 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(), 3708 &client_id); 3709 *params = client_id; 3710 } else { 3711 *params = 0; 3712 } 3713 } 3714 return true; 3715 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 3716 *num_written = 1; 3717 if (params) { 3718 if (state_.vertex_attrib_manager->element_array_buffer()) { 3719 GLuint client_id = 0; 3720 buffer_manager()->GetClientId( 3721 state_.vertex_attrib_manager->element_array_buffer( 3722 )->service_id(), &client_id); 3723 *params = client_id; 3724 } else { 3725 *params = 0; 3726 } 3727 } 3728 return true; 3729 case GL_FRAMEBUFFER_BINDING: 3730 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING) 3731 *num_written = 1; 3732 if (params) { 3733 FramebufferManager::FramebufferInfo* framebuffer = 3734 GetFramebufferInfoForTarget(GL_FRAMEBUFFER); 3735 if (framebuffer) { 3736 GLuint client_id = 0; 3737 framebuffer_manager()->GetClientId( 3738 framebuffer->service_id(), &client_id); 3739 *params = client_id; 3740 } else { 3741 *params = 0; 3742 } 3743 } 3744 return true; 3745 case GL_READ_FRAMEBUFFER_BINDING_EXT: 3746 *num_written = 1; 3747 if (params) { 3748 FramebufferManager::FramebufferInfo* framebuffer = 3749 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT); 3750 if (framebuffer) { 3751 GLuint client_id = 0; 3752 framebuffer_manager()->GetClientId( 3753 framebuffer->service_id(), &client_id); 3754 *params = client_id; 3755 } else { 3756 *params = 0; 3757 } 3758 } 3759 return true; 3760 case GL_RENDERBUFFER_BINDING: 3761 *num_written = 1; 3762 if (params) { 3763 RenderbufferManager::RenderbufferInfo* renderbuffer = 3764 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 3765 if (renderbuffer) { 3766 GLuint client_id = 0; 3767 renderbuffer_manager()->GetClientId( 3768 renderbuffer->service_id(), &client_id); 3769 *params = client_id; 3770 } else { 3771 *params = 0; 3772 } 3773 } 3774 return true; 3775 case GL_CURRENT_PROGRAM: 3776 *num_written = 1; 3777 if (params) { 3778 if (state_.current_program) { 3779 GLuint client_id = 0; 3780 program_manager()->GetClientId( 3781 state_.current_program->service_id(), &client_id); 3782 *params = client_id; 3783 } else { 3784 *params = 0; 3785 } 3786 } 3787 return true; 3788 case GL_TEXTURE_BINDING_2D: 3789 *num_written = 1; 3790 if (params) { 3791 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 3792 if (unit.bound_texture_2d) { 3793 GLuint client_id = 0; 3794 texture_manager()->GetClientId( 3795 unit.bound_texture_2d->service_id(), &client_id); 3796 *params = client_id; 3797 } else { 3798 *params = 0; 3799 } 3800 } 3801 return true; 3802 case GL_TEXTURE_BINDING_CUBE_MAP: 3803 *num_written = 1; 3804 if (params) { 3805 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 3806 if (unit.bound_texture_cube_map) { 3807 GLuint client_id = 0; 3808 texture_manager()->GetClientId( 3809 unit.bound_texture_cube_map->service_id(), &client_id); 3810 *params = client_id; 3811 } else { 3812 *params = 0; 3813 } 3814 } 3815 return true; 3816 case GL_TEXTURE_BINDING_EXTERNAL_OES: 3817 *num_written = 1; 3818 if (params) { 3819 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 3820 if (unit.bound_texture_external_oes) { 3821 GLuint client_id = 0; 3822 texture_manager()->GetClientId( 3823 unit.bound_texture_external_oes->service_id(), &client_id); 3824 *params = client_id; 3825 } else { 3826 *params = 0; 3827 } 3828 } 3829 return true; 3830 case GL_TEXTURE_BINDING_RECTANGLE_ARB: 3831 *num_written = 1; 3832 if (params) { 3833 TextureUnit& unit = state_.texture_units[state_.active_texture_unit]; 3834 if (unit.bound_texture_rectangle_arb) { 3835 GLuint client_id = 0; 3836 texture_manager()->GetClientId( 3837 unit.bound_texture_rectangle_arb->service_id(), &client_id); 3838 *params = client_id; 3839 } else { 3840 *params = 0; 3841 } 3842 } 3843 return true; 3844 case GL_UNPACK_FLIP_Y_CHROMIUM: 3845 *num_written = 1; 3846 if (params) { 3847 params[0] = unpack_flip_y_; 3848 } 3849 return true; 3850 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM: 3851 *num_written = 1; 3852 if (params) { 3853 params[0] = unpack_premultiply_alpha_; 3854 } 3855 return true; 3856 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM: 3857 *num_written = 1; 3858 if (params) { 3859 params[0] = unpack_unpremultiply_alpha_; 3860 } 3861 return true; 3862 default: 3863 *num_written = util_.GLGetNumValuesReturned(pname); 3864 return false; 3865 } 3866} 3867 3868bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet( 3869 GLenum pname, GLsizei* num_values) { 3870 if (GetStateAsGLint(pname, NULL, num_values)) { 3871 return true; 3872 } 3873 return GetHelper(pname, NULL, num_values); 3874} 3875 3876void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) { 3877 DCHECK(params); 3878 GLsizei num_written = 0; 3879 if (GetNumValuesReturnedForGLGet(pname, &num_written)) { 3880 scoped_array<GLint> values(new GLint[num_written]); 3881 if (!GetStateAsGLint(pname, values.get(), &num_written)) { 3882 GetHelper(pname, values.get(), &num_written); 3883 } 3884 for (GLsizei ii = 0; ii < num_written; ++ii) { 3885 params[ii] = static_cast<GLboolean>(values[ii]); 3886 } 3887 } else { 3888 glGetBooleanv(pname, params); 3889 } 3890} 3891 3892void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) { 3893 DCHECK(params); 3894 GLsizei num_written = 0; 3895 if (!GetStateAsGLfloat(pname, params, &num_written)) { 3896 if (GetHelper(pname, NULL, &num_written)) { 3897 scoped_array<GLint> values(new GLint[num_written]); 3898 GetHelper(pname, values.get(), &num_written); 3899 for (GLsizei ii = 0; ii < num_written; ++ii) { 3900 params[ii] = static_cast<GLfloat>(values[ii]); 3901 } 3902 } else { 3903 glGetFloatv(pname, params); 3904 } 3905 } 3906} 3907 3908void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) { 3909 DCHECK(params); 3910 GLsizei num_written; 3911 if (!GetStateAsGLint(pname, params, &num_written) && 3912 !GetHelper(pname, params, &num_written)) { 3913 glGetIntegerv(pname, params); 3914 } 3915} 3916 3917void GLES2DecoderImpl::DoGetProgramiv( 3918 GLuint program_id, GLenum pname, GLint* params) { 3919 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( 3920 program_id, "glGetProgramiv"); 3921 if (!info) { 3922 return; 3923 } 3924 info->GetProgramiv(pname, params); 3925} 3926 3927void GLES2DecoderImpl::DoBindAttribLocation( 3928 GLuint program, GLuint index, const char* name) { 3929 if (!StringIsValidForGLES(name)) { 3930 SetGLError(GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character"); 3931 return; 3932 } 3933 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) { 3934 SetGLError(GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix"); 3935 return; 3936 } 3937 if (index >= group_->max_vertex_attribs()) { 3938 SetGLError(GL_INVALID_VALUE, "glBindAttribLocation", "index out of range"); 3939 return; 3940 } 3941 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( 3942 program, "glBindAttribLocation"); 3943 if (!info) { 3944 return; 3945 } 3946 info->SetAttribLocationBinding(name, static_cast<GLint>(index)); 3947 glBindAttribLocation(info->service_id(), index, name); 3948} 3949 3950error::Error GLES2DecoderImpl::HandleBindAttribLocation( 3951 uint32 immediate_data_size, const gles2::BindAttribLocation& c) { 3952 GLuint program = static_cast<GLuint>(c.program); 3953 GLuint index = static_cast<GLuint>(c.index); 3954 uint32 name_size = c.data_size; 3955 const char* name = GetSharedMemoryAs<const char*>( 3956 c.name_shm_id, c.name_shm_offset, name_size); 3957 if (name == NULL) { 3958 return error::kOutOfBounds; 3959 } 3960 String name_str(name, name_size); 3961 DoBindAttribLocation(program, index, name_str.c_str()); 3962 return error::kNoError; 3963} 3964 3965error::Error GLES2DecoderImpl::HandleBindAttribLocationImmediate( 3966 uint32 immediate_data_size, const gles2::BindAttribLocationImmediate& c) { 3967 GLuint program = static_cast<GLuint>(c.program); 3968 GLuint index = static_cast<GLuint>(c.index); 3969 uint32 name_size = c.data_size; 3970 const char* name = GetImmediateDataAs<const char*>( 3971 c, name_size, immediate_data_size); 3972 if (name == NULL) { 3973 return error::kOutOfBounds; 3974 } 3975 String name_str(name, name_size); 3976 DoBindAttribLocation(program, index, name_str.c_str()); 3977 return error::kNoError; 3978} 3979 3980error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket( 3981 uint32 immediate_data_size, const gles2::BindAttribLocationBucket& c) { 3982 GLuint program = static_cast<GLuint>(c.program); 3983 GLuint index = static_cast<GLuint>(c.index); 3984 Bucket* bucket = GetBucket(c.name_bucket_id); 3985 if (!bucket || bucket->size() == 0) { 3986 return error::kInvalidArguments; 3987 } 3988 std::string name_str; 3989 if (!bucket->GetAsString(&name_str)) { 3990 return error::kInvalidArguments; 3991 } 3992 DoBindAttribLocation(program, index, name_str.c_str()); 3993 return error::kNoError; 3994} 3995 3996void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM( 3997 GLuint program, GLint location, const char* name) { 3998 if (!StringIsValidForGLES(name)) { 3999 SetGLError(GL_INVALID_VALUE, 4000 "glBindUniformLocationCHROMIUM", "Invalid character"); 4001 return; 4002 } 4003 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) { 4004 SetGLError(GL_INVALID_OPERATION, 4005 "glBindUniformLocationCHROMIUM", "reserved prefix"); 4006 return; 4007 } 4008 if (location < 0 || static_cast<uint32>(location) >= 4009 (group_->max_fragment_uniform_vectors() + 4010 group_->max_vertex_uniform_vectors()) * 4) { 4011 SetGLError(GL_INVALID_VALUE, 4012 "glBindUniformLocationCHROMIUM", "location out of range"); 4013 return; 4014 } 4015 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( 4016 program, "glBindUniformLocationCHROMIUM"); 4017 if (!info) { 4018 return; 4019 } 4020 if (!info->SetUniformLocationBinding(name, location)) { 4021 SetGLError(GL_INVALID_VALUE, 4022 "glBindUniformLocationCHROMIUM", "location out of range"); 4023 } 4024} 4025 4026error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM( 4027 uint32 immediate_data_size, const gles2::BindUniformLocationCHROMIUM& c) { 4028 GLuint program = static_cast<GLuint>(c.program); 4029 GLint location = static_cast<GLint>(c.location); 4030 uint32 name_size = c.data_size; 4031 const char* name = GetSharedMemoryAs<const char*>( 4032 c.name_shm_id, c.name_shm_offset, name_size); 4033 if (name == NULL) { 4034 return error::kOutOfBounds; 4035 } 4036 String name_str(name, name_size); 4037 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str()); 4038 return error::kNoError; 4039} 4040 4041error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMImmediate( 4042 uint32 immediate_data_size, 4043 const gles2::BindUniformLocationCHROMIUMImmediate& c) { 4044 GLuint program = static_cast<GLuint>(c.program); 4045 GLint location = static_cast<GLint>(c.location); 4046 uint32 name_size = c.data_size; 4047 const char* name = GetImmediateDataAs<const char*>( 4048 c, name_size, immediate_data_size); 4049 if (name == NULL) { 4050 return error::kOutOfBounds; 4051 } 4052 String name_str(name, name_size); 4053 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str()); 4054 return error::kNoError; 4055} 4056 4057error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket( 4058 uint32 immediate_data_size, 4059 const gles2::BindUniformLocationCHROMIUMBucket& c) { 4060 GLuint program = static_cast<GLuint>(c.program); 4061 GLint location = static_cast<GLint>(c.location); 4062 Bucket* bucket = GetBucket(c.name_bucket_id); 4063 if (!bucket || bucket->size() == 0) { 4064 return error::kInvalidArguments; 4065 } 4066 std::string name_str; 4067 if (!bucket->GetAsString(&name_str)) { 4068 return error::kInvalidArguments; 4069 } 4070 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str()); 4071 return error::kNoError; 4072} 4073 4074error::Error GLES2DecoderImpl::HandleDeleteShader( 4075 uint32 immediate_data_size, const gles2::DeleteShader& c) { 4076 GLuint client_id = c.shader; 4077 if (client_id) { 4078 ShaderManager::ShaderInfo* info = GetShaderInfo(client_id); 4079 if (info) { 4080 if (!info->IsDeleted()) { 4081 glDeleteShader(info->service_id()); 4082 shader_manager()->MarkAsDeleted(info); 4083 } 4084 } else { 4085 SetGLError(GL_INVALID_VALUE, "glDeleteShader", "unknown shader"); 4086 } 4087 } 4088 return error::kNoError; 4089} 4090 4091error::Error GLES2DecoderImpl::HandleDeleteProgram( 4092 uint32 immediate_data_size, const gles2::DeleteProgram& c) { 4093 GLuint client_id = c.program; 4094 if (client_id) { 4095 ProgramManager::ProgramInfo* info = GetProgramInfo(client_id); 4096 if (info) { 4097 if (!info->IsDeleted()) { 4098 program_manager()->MarkAsDeleted(shader_manager(), info); 4099 } 4100 } else { 4101 SetGLError(GL_INVALID_VALUE, "glDeleteProgram", "unknown program"); 4102 } 4103 } 4104 return error::kNoError; 4105} 4106 4107void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM( 4108 GLuint namespace_id, GLsizei n, const GLuint* ids) { 4109 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id); 4110 for (GLsizei ii = 0; ii < n; ++ii) { 4111 id_allocator->FreeID(ids[ii]); 4112 } 4113} 4114 4115error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM( 4116 uint32 immediate_data_size, const gles2::DeleteSharedIdsCHROMIUM& c) { 4117 GLuint namespace_id = static_cast<GLuint>(c.namespace_id); 4118 GLsizei n = static_cast<GLsizei>(c.n); 4119 uint32 data_size; 4120 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { 4121 return error::kOutOfBounds; 4122 } 4123 const GLuint* ids = GetSharedMemoryAs<const GLuint*>( 4124 c.ids_shm_id, c.ids_shm_offset, data_size); 4125 if (n < 0) { 4126 SetGLError(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0"); 4127 return error::kNoError; 4128 } 4129 if (ids == NULL) { 4130 return error::kOutOfBounds; 4131 } 4132 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids); 4133 return error::kNoError; 4134} 4135 4136void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM( 4137 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) { 4138 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id); 4139 if (id_offset == 0) { 4140 for (GLsizei ii = 0; ii < n; ++ii) { 4141 ids[ii] = id_allocator->AllocateID(); 4142 } 4143 } else { 4144 for (GLsizei ii = 0; ii < n; ++ii) { 4145 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset); 4146 id_offset = ids[ii] + 1; 4147 } 4148 } 4149} 4150 4151error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM( 4152 uint32 immediate_data_size, const gles2::GenSharedIdsCHROMIUM& c) { 4153 GLuint namespace_id = static_cast<GLuint>(c.namespace_id); 4154 GLuint id_offset = static_cast<GLuint>(c.id_offset); 4155 GLsizei n = static_cast<GLsizei>(c.n); 4156 uint32 data_size; 4157 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { 4158 return error::kOutOfBounds; 4159 } 4160 GLuint* ids = GetSharedMemoryAs<GLuint*>( 4161 c.ids_shm_id, c.ids_shm_offset, data_size); 4162 if (n < 0) { 4163 SetGLError(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0"); 4164 return error::kNoError; 4165 } 4166 if (ids == NULL) { 4167 return error::kOutOfBounds; 4168 } 4169 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids); 4170 return error::kNoError; 4171} 4172 4173void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM( 4174 GLuint namespace_id, GLsizei n, const GLuint* ids) { 4175 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id); 4176 for (GLsizei ii = 0; ii < n; ++ii) { 4177 if (!id_allocator->MarkAsUsed(ids[ii])) { 4178 for (GLsizei jj = 0; jj < ii; ++jj) { 4179 id_allocator->FreeID(ids[jj]); 4180 } 4181 SetGLError( 4182 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", 4183 "attempt to register id that already exists"); 4184 return; 4185 } 4186 } 4187} 4188 4189error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM( 4190 uint32 immediate_data_size, const gles2::RegisterSharedIdsCHROMIUM& c) { 4191 GLuint namespace_id = static_cast<GLuint>(c.namespace_id); 4192 GLsizei n = static_cast<GLsizei>(c.n); 4193 uint32 data_size; 4194 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { 4195 return error::kOutOfBounds; 4196 } 4197 GLuint* ids = GetSharedMemoryAs<GLuint*>( 4198 c.ids_shm_id, c.ids_shm_offset, data_size); 4199 if (n < 0) { 4200 SetGLError(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0"); 4201 return error::kNoError; 4202 } 4203 if (ids == NULL) { 4204 return error::kOutOfBounds; 4205 } 4206 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids); 4207 return error::kNoError; 4208} 4209 4210error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) { 4211 if (ShouldDeferDraws()) 4212 return error::kDeferCommandUntilLater; 4213 if (CheckBoundFramebuffersValid("glClear")) { 4214 UNSHIPPED_TRACE_EVENT_INSTANT2( 4215 "test_gpu", "DoClear", 4216 "red", state_.color_clear_red, 4217 "green", state_.color_clear_green); 4218 ApplyDirtyState(); 4219 glClear(mask); 4220 } 4221 return error::kNoError; 4222} 4223 4224error::Error GLES2DecoderImpl::HandleClear( 4225 uint32 immediate_data_size, const gles2::Clear& c) { 4226 GLbitfield mask = static_cast<GLbitfield>(c.mask); 4227 return DoClear(mask); 4228} 4229 4230void GLES2DecoderImpl::DoFramebufferRenderbuffer( 4231 GLenum target, GLenum attachment, GLenum renderbuffertarget, 4232 GLuint client_renderbuffer_id) { 4233 FramebufferManager::FramebufferInfo* framebuffer_info = 4234 GetFramebufferInfoForTarget(target); 4235 if (!framebuffer_info) { 4236 SetGLError(GL_INVALID_OPERATION, 4237 "glFramebufferRenderbuffer", "no framebuffer bound"); 4238 return; 4239 } 4240 GLuint service_id = 0; 4241 RenderbufferManager::RenderbufferInfo* info = NULL; 4242 if (client_renderbuffer_id) { 4243 info = GetRenderbufferInfo(client_renderbuffer_id); 4244 if (!info) { 4245 SetGLError(GL_INVALID_OPERATION, 4246 "glFramebufferRenderbuffer", "unknown renderbuffer"); 4247 return; 4248 } 4249 service_id = info->service_id(); 4250 } 4251 CopyRealGLErrorsToWrapper(); 4252 glFramebufferRenderbufferEXT( 4253 target, attachment, renderbuffertarget, service_id); 4254 GLenum error = PeekGLError(); 4255 if (error == GL_NO_ERROR) { 4256 framebuffer_info->AttachRenderbuffer(attachment, info); 4257 } 4258 if (framebuffer_info == state_.bound_draw_framebuffer) { 4259 clear_state_dirty_ = true; 4260 } 4261} 4262 4263void GLES2DecoderImpl::DoDisable(GLenum cap) { 4264 if (SetCapabilityState(cap, false)) { 4265 glDisable(cap); 4266 } 4267} 4268 4269void GLES2DecoderImpl::DoEnable(GLenum cap) { 4270 if (SetCapabilityState(cap, true)) { 4271 glEnable(cap); 4272 } 4273} 4274 4275void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) { 4276 state_.z_near = std::min(1.0f, std::max(0.0f, znear)); 4277 state_.z_far = std::min(1.0f, std::max(0.0f, zfar)); 4278 glDepthRange(znear, zfar); 4279} 4280 4281void GLES2DecoderImpl::DoHint(GLenum target, GLenum mode) { 4282 switch (target) { 4283 case GL_GENERATE_MIPMAP_HINT: 4284 state_.hint_generate_mipmap = mode; 4285 break; 4286 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: 4287 state_.hint_fragment_shader_derivative = mode; 4288 break; 4289 default: 4290 NOTREACHED(); 4291 } 4292 glHint(target, mode); 4293} 4294 4295void GLES2DecoderImpl::DoSampleCoverage (GLclampf value, GLboolean invert) { 4296 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value)); 4297 state_.sample_coverage_invert = (invert != 0); 4298 glSampleCoverage(state_.sample_coverage_value, invert); 4299} 4300 4301// Assumes framebuffer is complete. 4302void GLES2DecoderImpl::ClearUnclearedAttachments( 4303 GLenum target, FramebufferManager::FramebufferInfo* info) { 4304 if (target == GL_READ_FRAMEBUFFER_EXT) { 4305 // bind this to the DRAW point, clear then bind back to READ 4306 // TODO(gman): I don't think there is any guarantee that an FBO that 4307 // is complete on the READ attachment will be complete as a DRAW 4308 // attachment. 4309 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); 4310 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, info->service_id()); 4311 } 4312 GLbitfield clear_bits = 0; 4313 if (info->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) { 4314 glClearColor( 4315 0.0f, 0.0f, 0.0f, 4316 (GLES2Util::GetChannelsForFormat( 4317 info->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f : 1.0f); 4318 glColorMask(true, true, true, true); 4319 clear_bits |= GL_COLOR_BUFFER_BIT; 4320 } 4321 4322 if (info->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) || 4323 info->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) { 4324 glClearStencil(0); 4325 glStencilMask(-1); 4326 clear_bits |= GL_STENCIL_BUFFER_BIT; 4327 } 4328 4329 if (info->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) || 4330 info->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) { 4331 glClearDepth(1.0f); 4332 glDepthMask(true); 4333 clear_bits |= GL_DEPTH_BUFFER_BIT; 4334 } 4335 4336 glDisable(GL_SCISSOR_TEST); 4337 glClear(clear_bits); 4338 4339 framebuffer_manager()->MarkAttachmentsAsCleared( 4340 info, renderbuffer_manager(), texture_manager()); 4341 4342 RestoreClearState(); 4343 4344 if (target == GL_READ_FRAMEBUFFER_EXT) { 4345 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, info->service_id()); 4346 FramebufferManager::FramebufferInfo* framebuffer = 4347 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 4348 GLuint service_id = 4349 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId(); 4350 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id); 4351 } 4352} 4353 4354void GLES2DecoderImpl::RestoreClearState() { 4355 clear_state_dirty_ = true; 4356 glClearColor( 4357 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue, 4358 state_.color_clear_alpha); 4359 glClearStencil(state_.stencil_clear); 4360 glClearDepth(state_.depth_clear); 4361 if (state_.enable_flags.scissor_test) { 4362 glEnable(GL_SCISSOR_TEST); 4363 } 4364} 4365 4366GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) { 4367 FramebufferManager::FramebufferInfo* framebuffer = 4368 GetFramebufferInfoForTarget(target); 4369 if (!framebuffer) { 4370 return GL_FRAMEBUFFER_COMPLETE; 4371 } 4372 GLenum completeness = framebuffer->IsPossiblyComplete(); 4373 if (completeness != GL_FRAMEBUFFER_COMPLETE) { 4374 return completeness; 4375 } 4376 return framebuffer->GetStatus(texture_manager(), target); 4377} 4378 4379void GLES2DecoderImpl::DoFramebufferTexture2D( 4380 GLenum target, GLenum attachment, GLenum textarget, 4381 GLuint client_texture_id, GLint level) { 4382 FramebufferManager::FramebufferInfo* framebuffer_info = 4383 GetFramebufferInfoForTarget(target); 4384 if (!framebuffer_info) { 4385 SetGLError(GL_INVALID_OPERATION, 4386 "glFramebufferTexture2D", "no framebuffer bound."); 4387 return; 4388 } 4389 GLuint service_id = 0; 4390 TextureManager::TextureInfo* info = NULL; 4391 if (client_texture_id) { 4392 info = GetTextureInfo(client_texture_id); 4393 if (!info) { 4394 SetGLError(GL_INVALID_OPERATION, 4395 "glFramebufferTexture2D", "unknown texture"); 4396 return; 4397 } 4398 service_id = info->service_id(); 4399 } 4400 4401 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) { 4402 SetGLError(GL_INVALID_VALUE, 4403 "glFramebufferTexture2D", "level out of range"); 4404 return; 4405 } 4406 4407 CopyRealGLErrorsToWrapper(); 4408 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level); 4409 GLenum error = PeekGLError(); 4410 if (error == GL_NO_ERROR) { 4411 framebuffer_info->AttachTexture(attachment, info, textarget, level); 4412 } 4413 if (framebuffer_info == state_.bound_draw_framebuffer) { 4414 clear_state_dirty_ = true; 4415 } 4416} 4417 4418void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv( 4419 GLenum target, GLenum attachment, GLenum pname, GLint* params) { 4420 FramebufferManager::FramebufferInfo* framebuffer_info = 4421 GetFramebufferInfoForTarget(target); 4422 if (!framebuffer_info) { 4423 SetGLError(GL_INVALID_OPERATION, 4424 "glFramebufferAttachmentParameteriv", "no framebuffer bound"); 4425 return; 4426 } 4427 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params); 4428 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) { 4429 GLint type = 0; 4430 GLuint client_id = 0; 4431 glGetFramebufferAttachmentParameterivEXT( 4432 target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type); 4433 switch (type) { 4434 case GL_RENDERBUFFER: { 4435 renderbuffer_manager()->GetClientId(*params, &client_id); 4436 break; 4437 } 4438 case GL_TEXTURE: { 4439 texture_manager()->GetClientId(*params, &client_id); 4440 break; 4441 } 4442 default: 4443 break; 4444 } 4445 *params = client_id; 4446 } 4447} 4448 4449void GLES2DecoderImpl::DoGetRenderbufferParameteriv( 4450 GLenum target, GLenum pname, GLint* params) { 4451 RenderbufferManager::RenderbufferInfo* renderbuffer = 4452 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 4453 if (!renderbuffer) { 4454 SetGLError(GL_INVALID_OPERATION, 4455 "glGetRenderbufferParameteriv", "no renderbuffer bound"); 4456 return; 4457 } 4458 switch (pname) { 4459 case GL_RENDERBUFFER_INTERNAL_FORMAT: 4460 *params = renderbuffer->internal_format(); 4461 break; 4462 case GL_RENDERBUFFER_WIDTH: 4463 *params = renderbuffer->width(); 4464 break; 4465 case GL_RENDERBUFFER_HEIGHT: 4466 *params = renderbuffer->height(); 4467 break; 4468 default: 4469 glGetRenderbufferParameterivEXT(target, pname, params); 4470 break; 4471 } 4472} 4473 4474void GLES2DecoderImpl::DoBlitFramebufferEXT( 4475 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 4476 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 4477 GLbitfield mask, GLenum filter) { 4478 if (!features().chromium_framebuffer_multisample) { 4479 SetGLError(GL_INVALID_OPERATION, 4480 "glBlitFramebufferEXT", "function not available"); 4481 } 4482 if (IsAngle()) { 4483 glBlitFramebufferANGLE( 4484 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); 4485 } else { 4486 glBlitFramebufferEXT( 4487 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); 4488 } 4489 UNSHIPPED_TRACE_EVENT_INSTANT1("test_gpu", "DoBlit", "width", srcX1 - srcX0); 4490} 4491 4492void GLES2DecoderImpl::DoRenderbufferStorageMultisample( 4493 GLenum target, GLsizei samples, GLenum internalformat, 4494 GLsizei width, GLsizei height) { 4495 if (!features().chromium_framebuffer_multisample) { 4496 SetGLError(GL_INVALID_OPERATION, 4497 "glRenderbufferStorageMultisampleEXT", "function not available"); 4498 return; 4499 } 4500 4501 RenderbufferManager::RenderbufferInfo* renderbuffer = 4502 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 4503 if (!renderbuffer) { 4504 SetGLError(GL_INVALID_OPERATION, 4505 "glGetRenderbufferStorageMultisample", "no renderbuffer bound"); 4506 return; 4507 } 4508 4509 if (samples > renderbuffer_manager()->max_samples()) { 4510 SetGLError(GL_INVALID_VALUE, 4511 "glGetRenderbufferStorageMultisample", "samples too large"); 4512 return; 4513 } 4514 4515 if (width > renderbuffer_manager()->max_renderbuffer_size() || 4516 height > renderbuffer_manager()->max_renderbuffer_size()) { 4517 SetGLError(GL_INVALID_VALUE, 4518 "glGetRenderbufferStorageMultisample", "size too large"); 4519 return; 4520 } 4521 4522 GLenum impl_format = internalformat; 4523 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 4524 switch (impl_format) { 4525 case GL_DEPTH_COMPONENT16: 4526 impl_format = GL_DEPTH_COMPONENT; 4527 break; 4528 case GL_RGBA4: 4529 case GL_RGB5_A1: 4530 impl_format = GL_RGBA; 4531 break; 4532 case GL_RGB565: 4533 impl_format = GL_RGB; 4534 break; 4535 } 4536 } 4537 4538 CopyRealGLErrorsToWrapper(); 4539 if (IsAngle()) { 4540 glRenderbufferStorageMultisampleANGLE( 4541 target, samples, impl_format, width, height); 4542 } else { 4543 glRenderbufferStorageMultisampleEXT( 4544 target, samples, impl_format, width, height); 4545 } 4546 GLenum error = PeekGLError(); 4547 if (error == GL_NO_ERROR) { 4548 // TODO(gman): If renderbuffers tracked which framebuffers they were 4549 // attached to we could just mark those framebuffers as not complete. 4550 framebuffer_manager()->IncFramebufferStateChangeCount(); 4551 renderbuffer_manager()->SetInfo( 4552 renderbuffer, samples, internalformat, width, height); 4553 } 4554} 4555 4556void GLES2DecoderImpl::DoRenderbufferStorage( 4557 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { 4558 RenderbufferManager::RenderbufferInfo* renderbuffer = 4559 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); 4560 if (!renderbuffer) { 4561 SetGLError(GL_INVALID_OPERATION, 4562 "glGetRenderbufferStorage", "no renderbuffer bound"); 4563 return; 4564 } 4565 4566 if (width > renderbuffer_manager()->max_renderbuffer_size() || 4567 height > renderbuffer_manager()->max_renderbuffer_size()) { 4568 SetGLError(GL_INVALID_VALUE, 4569 "glGetRenderbufferStorage", "size too large"); 4570 return; 4571 } 4572 4573 GLenum impl_format = internalformat; 4574 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { 4575 switch (impl_format) { 4576 case GL_DEPTH_COMPONENT16: 4577 impl_format = GL_DEPTH_COMPONENT; 4578 break; 4579 case GL_RGBA4: 4580 case GL_RGB5_A1: 4581 impl_format = GL_RGBA; 4582 break; 4583 case GL_RGB565: 4584 impl_format = GL_RGB; 4585 break; 4586 } 4587 } 4588 4589 CopyRealGLErrorsToWrapper(); 4590 glRenderbufferStorageEXT(target, impl_format, width, height); 4591 GLenum error = PeekGLError(); 4592 if (error == GL_NO_ERROR) { 4593 // TODO(gman): If tetxures tracked which framebuffers they were attached to 4594 // we could just mark those framebuffers as not complete. 4595 framebuffer_manager()->IncFramebufferStateChangeCount(); 4596 renderbuffer_manager()->SetInfo( 4597 renderbuffer, 0, internalformat, width, height); 4598 } 4599} 4600 4601void GLES2DecoderImpl::DoLinkProgram(GLuint program) { 4602 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram"); 4603 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( 4604 program, "glLinkProgram"); 4605 if (!info) { 4606 return; 4607 } 4608 4609 ShaderTranslator* vertex_translator = NULL; 4610 ShaderTranslator* fragment_translator = NULL; 4611 if (use_shader_translator_) { 4612 vertex_translator = vertex_translator_; 4613 fragment_translator = fragment_translator_; 4614 } 4615 if (info->Link(shader_manager(), 4616 vertex_translator, 4617 fragment_translator, 4618 feature_info_)) { 4619 if (info == state_.current_program.get()) { 4620 if (workarounds().use_current_program_after_successful_link) { 4621 glUseProgram(info->service_id()); 4622 } 4623 program_manager()->ClearUniforms(info); 4624 } 4625 } 4626}; 4627 4628void GLES2DecoderImpl::DoTexParameterf( 4629 GLenum target, GLenum pname, GLfloat param) { 4630 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 4631 if (!info) { 4632 SetGLError(GL_INVALID_VALUE, "glTexParameterf", "unknown texture"); 4633 return; 4634 } 4635 4636 if (!texture_manager()->SetParameter( 4637 info, pname, static_cast<GLint>(param))) { 4638 SetGLErrorInvalidEnum("glTexParameterf", pname, "pname"); 4639 return; 4640 } 4641 glTexParameterf(target, pname, param); 4642} 4643 4644void GLES2DecoderImpl::DoTexParameteri( 4645 GLenum target, GLenum pname, GLint param) { 4646 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 4647 if (!info) { 4648 SetGLError(GL_INVALID_VALUE, "glTexParameteri", "unknown texture"); 4649 return; 4650 } 4651 4652 if (!texture_manager()->SetParameter(info, pname, param)) { 4653 SetGLErrorInvalidEnum("glTexParameteri", pname, "pname"); 4654 return; 4655 } 4656 glTexParameteri(target, pname, param); 4657} 4658 4659void GLES2DecoderImpl::DoTexParameterfv( 4660 GLenum target, GLenum pname, const GLfloat* params) { 4661 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 4662 if (!info) { 4663 SetGLError(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture"); 4664 return; 4665 } 4666 4667 if (!texture_manager()->SetParameter( 4668 info, pname, static_cast<GLint>(params[0]))) { 4669 SetGLErrorInvalidEnum("glTexParameterfv", pname, "pname"); 4670 return; 4671 } 4672 glTexParameterfv(target, pname, params); 4673} 4674 4675void GLES2DecoderImpl::DoTexParameteriv( 4676 GLenum target, GLenum pname, const GLint* params) { 4677 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 4678 if (!info) { 4679 SetGLError(GL_INVALID_VALUE, "glTexParameteriv", "unknown texture"); 4680 return; 4681 } 4682 4683 if (!texture_manager()->SetParameter(info, pname, *params)) { 4684 SetGLErrorInvalidEnum("glTexParameteriv", pname, "pname"); 4685 return; 4686 } 4687 glTexParameteriv(target, pname, params); 4688} 4689 4690bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) { 4691 if (!state_.current_program) { 4692 // The program does not exist. 4693 SetGLError(GL_INVALID_OPERATION, function_name, "no program in use"); 4694 return false; 4695 } 4696 if (!state_.current_program->InUse()) { 4697 SetGLError(GL_INVALID_OPERATION, function_name, "program not linked"); 4698 return false; 4699 } 4700 return true; 4701} 4702 4703bool GLES2DecoderImpl::CheckCurrentProgramForUniform( 4704 GLint location, const char* function_name) { 4705 if (!CheckCurrentProgram(function_name)) { 4706 return false; 4707 } 4708 return location != -1; 4709} 4710 4711bool GLES2DecoderImpl::PrepForSetUniformByLocation( 4712 GLint fake_location, const char* function_name, 4713 GLint* real_location, GLenum* type, GLsizei* count) { 4714 DCHECK(type); 4715 DCHECK(count); 4716 DCHECK(real_location); 4717 if (!CheckCurrentProgramForUniform(fake_location, function_name)) { 4718 return false; 4719 } 4720 GLint array_index = -1; 4721 const ProgramManager::ProgramInfo::UniformInfo* info = 4722 state_.current_program->GetUniformInfoByFakeLocation( 4723 fake_location, real_location, &array_index); 4724 if (!info) { 4725 SetGLError(GL_INVALID_OPERATION, function_name, "unknown location"); 4726 return false; 4727 } 4728 if (*count > 1 && !info->is_array) { 4729 SetGLError( 4730 GL_INVALID_OPERATION, function_name, "count > 1 for non-array"); 4731 return false; 4732 } 4733 *count = std::min(info->size - array_index, *count); 4734 if (*count <= 0) { 4735 return false; 4736 } 4737 *type = info->type; 4738 return true; 4739} 4740 4741void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) { 4742 GLenum type = 0; 4743 GLsizei count = 1; 4744 GLint real_location = -1; 4745 if (!PrepForSetUniformByLocation( 4746 fake_location, "glUniform1iv", &real_location, &type, &count)) { 4747 return; 4748 } 4749 if (!state_.current_program->SetSamplers( 4750 state_.texture_units.size(), fake_location, 1, &v0)) { 4751 SetGLError(GL_INVALID_VALUE, "glUniform1i", "texture unit out of range"); 4752 return; 4753 } 4754 glUniform1i(real_location, v0); 4755} 4756 4757void GLES2DecoderImpl::DoUniform1iv( 4758 GLint fake_location, GLsizei count, const GLint *value) { 4759 GLenum type = 0; 4760 GLint real_location = -1; 4761 if (!PrepForSetUniformByLocation( 4762 fake_location, "glUniform1iv", &real_location, &type, &count)) { 4763 return; 4764 } 4765 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB || 4766 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) { 4767 if (!state_.current_program->SetSamplers( 4768 state_.texture_units.size(), fake_location, count, value)) { 4769 SetGLError(GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range"); 4770 return; 4771 } 4772 } 4773 glUniform1iv(real_location, count, value); 4774} 4775 4776void GLES2DecoderImpl::DoUniform1fv( 4777 GLint fake_location, GLsizei count, const GLfloat* value) { 4778 GLenum type = 0; 4779 GLint real_location = -1; 4780 if (!PrepForSetUniformByLocation( 4781 fake_location, "glUniform1fv", &real_location, &type, &count)) { 4782 return; 4783 } 4784 if (type == GL_BOOL) { 4785 scoped_array<GLint> temp(new GLint[count]); 4786 for (GLsizei ii = 0; ii < count; ++ii) { 4787 temp[ii] = static_cast<GLint>(value[ii] != 0.0f); 4788 } 4789 DoUniform1iv(real_location, count, temp.get()); 4790 } else { 4791 glUniform1fv(real_location, count, value); 4792 } 4793} 4794 4795void GLES2DecoderImpl::DoUniform2fv( 4796 GLint fake_location, GLsizei count, const GLfloat* value) { 4797 GLenum type = 0; 4798 GLint real_location = -1; 4799 if (!PrepForSetUniformByLocation( 4800 fake_location, "glUniform2fv", &real_location, &type, &count)) { 4801 return; 4802 } 4803 if (type == GL_BOOL_VEC2) { 4804 GLsizei num_values = count * 2; 4805 scoped_array<GLint> temp(new GLint[num_values]); 4806 for (GLsizei ii = 0; ii < num_values; ++ii) { 4807 temp[ii] = static_cast<GLint>(value[ii] != 0.0f); 4808 } 4809 glUniform2iv(real_location, count, temp.get()); 4810 } else { 4811 glUniform2fv(real_location, count, value); 4812 } 4813} 4814 4815void GLES2DecoderImpl::DoUniform3fv( 4816 GLint fake_location, GLsizei count, const GLfloat* value) { 4817 GLenum type = 0; 4818 GLint real_location = -1; 4819 if (!PrepForSetUniformByLocation( 4820 fake_location, "glUniform3fv", &real_location, &type, &count)) { 4821 return; 4822 } 4823 if (type == GL_BOOL_VEC3) { 4824 GLsizei num_values = count * 3; 4825 scoped_array<GLint> temp(new GLint[num_values]); 4826 for (GLsizei ii = 0; ii < num_values; ++ii) { 4827 temp[ii] = static_cast<GLint>(value[ii] != 0.0f); 4828 } 4829 glUniform3iv(real_location, count, temp.get()); 4830 } else { 4831 glUniform3fv(real_location, count, value); 4832 } 4833} 4834 4835void GLES2DecoderImpl::DoUniform4fv( 4836 GLint fake_location, GLsizei count, const GLfloat* value) { 4837 GLenum type = 0; 4838 GLint real_location = -1; 4839 if (!PrepForSetUniformByLocation( 4840 fake_location, "glUniform4fv", &real_location, &type, &count)) { 4841 return; 4842 } 4843 if (type == GL_BOOL_VEC4) { 4844 GLsizei num_values = count * 4; 4845 scoped_array<GLint> temp(new GLint[num_values]); 4846 for (GLsizei ii = 0; ii < num_values; ++ii) { 4847 temp[ii] = static_cast<GLint>(value[ii] != 0.0f); 4848 } 4849 glUniform4iv(real_location, count, temp.get()); 4850 } else { 4851 glUniform4fv(real_location, count, value); 4852 } 4853} 4854 4855void GLES2DecoderImpl::DoUniform2iv( 4856 GLint fake_location, GLsizei count, const GLint* value) { 4857 GLenum type = 0; 4858 GLint real_location = -1; 4859 if (!PrepForSetUniformByLocation( 4860 fake_location, "glUniform2iv", &real_location, &type, &count)) { 4861 return; 4862 } 4863 glUniform2iv(real_location, count, value); 4864} 4865 4866void GLES2DecoderImpl::DoUniform3iv( 4867 GLint fake_location, GLsizei count, const GLint* value) { 4868 GLenum type = 0; 4869 GLint real_location = -1; 4870 if (!PrepForSetUniformByLocation( 4871 fake_location, "glUniform3iv", &real_location, &type, &count)) { 4872 return; 4873 } 4874 glUniform3iv(real_location, count, value); 4875} 4876 4877void GLES2DecoderImpl::DoUniform4iv( 4878 GLint fake_location, GLsizei count, const GLint* value) { 4879 GLenum type = 0; 4880 GLint real_location = -1; 4881 if (!PrepForSetUniformByLocation( 4882 fake_location, "glUniform4iv", &real_location, &type, &count)) { 4883 return; 4884 } 4885 glUniform4iv(real_location, count, value); 4886} 4887 4888void GLES2DecoderImpl::DoUniformMatrix2fv( 4889 GLint fake_location, GLsizei count, GLboolean transpose, 4890 const GLfloat* value) { 4891 GLenum type = 0; 4892 GLint real_location = -1; 4893 if (!PrepForSetUniformByLocation( 4894 fake_location, "glUniformMatrix2fv", &real_location, &type, &count)) { 4895 return; 4896 } 4897 glUniformMatrix2fv(real_location, count, transpose, value); 4898} 4899 4900void GLES2DecoderImpl::DoUniformMatrix3fv( 4901 GLint fake_location, GLsizei count, GLboolean transpose, 4902 const GLfloat* value) { 4903 GLenum type = 0; 4904 GLint real_location = -1; 4905 if (!PrepForSetUniformByLocation( 4906 fake_location, "glUniformMatrix3fv", &real_location, &type, &count)) { 4907 return; 4908 } 4909 glUniformMatrix3fv(real_location, count, transpose, value); 4910} 4911 4912void GLES2DecoderImpl::DoUniformMatrix4fv( 4913 GLint fake_location, GLsizei count, GLboolean transpose, 4914 const GLfloat* value) { 4915 GLenum type = 0; 4916 GLint real_location = -1; 4917 if (!PrepForSetUniformByLocation( 4918 fake_location, "glUniformMatrix4fv", &real_location, &type, &count)) { 4919 return; 4920 } 4921 glUniformMatrix4fv(real_location, count, transpose, value); 4922} 4923 4924void GLES2DecoderImpl::DoUseProgram(GLuint program) { 4925 GLuint service_id = 0; 4926 ProgramManager::ProgramInfo* info = NULL; 4927 if (program) { 4928 info = GetProgramInfoNotShader(program, "glUseProgram"); 4929 if (!info) { 4930 return; 4931 } 4932 if (!info->IsValid()) { 4933 // Program was not linked successfully. (ie, glLinkProgram) 4934 SetGLError(GL_INVALID_OPERATION, "glUseProgram", "program not linked"); 4935 return; 4936 } 4937 service_id = info->service_id(); 4938 } 4939 if (state_.current_program) { 4940 program_manager()->UnuseProgram(shader_manager(), state_.current_program); 4941 } 4942 state_.current_program = info; 4943 glUseProgram(service_id); 4944 if (state_.current_program) { 4945 program_manager()->UseProgram(state_.current_program); 4946 } 4947} 4948 4949uint32 GLES2DecoderImpl::GetGLError() { 4950 // Check the GL error first, then our wrapped error. 4951 GLenum error = glGetError(); 4952 if (error == GL_NO_ERROR && error_bits_ != 0) { 4953 for (uint32 mask = 1; mask != 0; mask = mask << 1) { 4954 if ((error_bits_ & mask) != 0) { 4955 error = GLES2Util::GLErrorBitToGLError(mask); 4956 break; 4957 } 4958 } 4959 } 4960 4961 if (error != GL_NO_ERROR) { 4962 // There was an error, clear the corresponding wrapped error. 4963 error_bits_ &= ~GLES2Util::GLErrorToErrorBit(error); 4964 } 4965 return error; 4966} 4967 4968GLenum GLES2DecoderImpl::PeekGLError() { 4969 GLenum error = glGetError(); 4970 if (error != GL_NO_ERROR) { 4971 SetGLError(error, "", ""); 4972 } 4973 return error; 4974} 4975 4976void GLES2DecoderImpl::SetGLError( 4977 GLenum error, const char* function_name, const char* msg) { 4978 if (msg) { 4979 last_error_ = msg; 4980 LogMessage(GetLogPrefix() + ": " + std::string("GL ERROR :") + 4981 GLES2Util::GetStringEnum(error) + " : " + 4982 function_name + ": " + msg); 4983 } 4984 error_bits_ |= GLES2Util::GLErrorToErrorBit(error); 4985} 4986 4987void GLES2DecoderImpl::SetGLErrorInvalidEnum( 4988 const char* function_name, GLenum value, const char* label) { 4989 SetGLError(GL_INVALID_ENUM, function_name, 4990 (std::string(label) + " was " + 4991 GLES2Util::GetStringEnum(value)).c_str()); 4992} 4993 4994const std::string& GLES2DecoderImpl::GetLogPrefix() const { 4995 const std::string& prefix(debug_marker_manager_.GetMarker()); 4996 return prefix.empty() ? this_in_hex_ : prefix; 4997} 4998 4999void GLES2DecoderImpl::LogMessage(const std::string& msg) { 5000 if (log_message_count_ < kMaxLogMessages || 5001 CommandLine::ForCurrentProcess()->HasSwitch( 5002 switches::kDisableGLErrorLimit)) { 5003 ++log_message_count_; 5004 // LOG this unless logging is turned off as any chromium code that 5005 // generates these errors probably has a bug. 5006 if (log_synthesized_gl_errors()) { 5007 LOG(ERROR) << msg; 5008 } 5009 if (!msg_callback_.is_null()) { 5010 msg_callback_.Run(0, msg); 5011 } 5012 } else { 5013 if (log_message_count_ == kMaxLogMessages) { 5014 ++log_message_count_; 5015 LOG(ERROR) 5016 << "Too many GL errors, not reporting any more for this context." 5017 << " use --disable-gl-error-limit to see all errors."; 5018 } 5019 } 5020} 5021 5022void GLES2DecoderImpl::RenderWarning(const std::string& msg) { 5023 LogMessage(std::string("RENDER WARNING: ") + msg); 5024} 5025 5026void GLES2DecoderImpl::PerformanceWarning(const std::string& msg) { 5027 LogMessage(std::string("PERFORMANCE WARNING: ") + msg); 5028} 5029 5030void GLES2DecoderImpl::ForceCompileShaderIfPending( 5031 ShaderManager::ShaderInfo* info) { 5032 if (info->compilation_status() == 5033 ShaderManager::ShaderInfo::PENDING_DEFERRED_COMPILE) { 5034 ShaderTranslator* translator = NULL; 5035 if (use_shader_translator_) { 5036 translator = info->shader_type() == GL_VERTEX_SHADER ? 5037 vertex_translator_.get() : fragment_translator_.get(); 5038 } 5039 // We know there will be no errors, because we only defer compilation on 5040 // shaders that were previously compiled successfully. 5041 program_manager()->ForceCompileShader(info->deferred_compilation_source(), 5042 info, 5043 translator, 5044 feature_info_); 5045 } 5046} 5047 5048void GLES2DecoderImpl::CopyRealGLErrorsToWrapper() { 5049 GLenum error; 5050 while ((error = glGetError()) != GL_NO_ERROR) { 5051 SetGLError(error, "", NULL); 5052 } 5053} 5054 5055void GLES2DecoderImpl::ClearRealGLErrors() { 5056 GLenum error; 5057 while ((error = glGetError()) != GL_NO_ERROR) { 5058 if (error != GL_OUT_OF_MEMORY) { 5059 // GL_OUT_OF_MEMORY can legally happen on lost device. 5060 NOTREACHED() << "GL error " << error << " was unhandled."; 5061 } 5062 } 5063} 5064 5065bool GLES2DecoderImpl::SetBlackTextureForNonRenderableTextures() { 5066 DCHECK(state_.current_program); 5067 // Only check if there are some unrenderable textures. 5068 if (!texture_manager()->HaveUnrenderableTextures()) { 5069 return false; 5070 } 5071 bool textures_set = false; 5072 const ProgramManager::ProgramInfo::SamplerIndices& sampler_indices = 5073 state_.current_program->sampler_indices(); 5074 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) { 5075 const ProgramManager::ProgramInfo::UniformInfo* uniform_info = 5076 state_.current_program->GetUniformInfo(sampler_indices[ii]); 5077 DCHECK(uniform_info); 5078 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) { 5079 GLuint texture_unit_index = uniform_info->texture_units[jj]; 5080 if (texture_unit_index < state_.texture_units.size()) { 5081 TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; 5082 TextureManager::TextureInfo* texture_info = 5083 texture_unit.GetInfoForSamplerType(uniform_info->type); 5084 if (!texture_info || !texture_manager()->CanRender(texture_info)) { 5085 textures_set = true; 5086 glActiveTexture(GL_TEXTURE0 + texture_unit_index); 5087 glBindTexture( 5088 GetBindTargetForSamplerType(uniform_info->type), 5089 texture_manager()->black_texture_id(uniform_info->type)); 5090 RenderWarning( 5091 std::string("texture bound to texture unit ") + 5092 base::IntToString(texture_unit_index) + 5093 " is not renderable. It maybe non-power-of-2 and have " 5094 " incompatible texture filtering or is not " 5095 "'texture complete'"); 5096 } 5097 } 5098 // else: should this be an error? 5099 } 5100 } 5101 return textures_set; 5102} 5103 5104void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() { 5105 DCHECK(state_.current_program); 5106 const ProgramManager::ProgramInfo::SamplerIndices& sampler_indices = 5107 state_.current_program->sampler_indices(); 5108 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) { 5109 const ProgramManager::ProgramInfo::UniformInfo* uniform_info = 5110 state_.current_program->GetUniformInfo(sampler_indices[ii]); 5111 DCHECK(uniform_info); 5112 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) { 5113 GLuint texture_unit_index = uniform_info->texture_units[jj]; 5114 if (texture_unit_index < state_.texture_units.size()) { 5115 TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; 5116 TextureManager::TextureInfo* texture_info = 5117 uniform_info->type == GL_SAMPLER_2D ? 5118 texture_unit.bound_texture_2d : 5119 texture_unit.bound_texture_cube_map; 5120 if (!texture_info || !texture_manager()->CanRender(texture_info)) { 5121 glActiveTexture(GL_TEXTURE0 + texture_unit_index); 5122 // Get the texture info that was previously bound here. 5123 texture_info = texture_unit.bind_target == GL_TEXTURE_2D ? 5124 texture_unit.bound_texture_2d : 5125 texture_unit.bound_texture_cube_map; 5126 glBindTexture(texture_unit.bind_target, 5127 texture_info ? texture_info->service_id() : 0); 5128 } 5129 } 5130 } 5131 } 5132 // Set the active texture back to whatever the user had it as. 5133 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit); 5134} 5135 5136bool GLES2DecoderImpl::ClearUnclearedTextures() { 5137 // Only check if there are some uncleared textures. 5138 if (!texture_manager()->HaveUnsafeTextures()) { 5139 return true; 5140 } 5141 5142 // 1: Check all textures we are about to render with. 5143 if (state_.current_program) { 5144 const ProgramManager::ProgramInfo::SamplerIndices& sampler_indices = 5145 state_.current_program->sampler_indices(); 5146 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) { 5147 const ProgramManager::ProgramInfo::UniformInfo* uniform_info = 5148 state_.current_program->GetUniformInfo(sampler_indices[ii]); 5149 DCHECK(uniform_info); 5150 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) { 5151 GLuint texture_unit_index = uniform_info->texture_units[jj]; 5152 if (texture_unit_index < state_.texture_units.size()) { 5153 TextureUnit& texture_unit = state_.texture_units[texture_unit_index]; 5154 TextureManager::TextureInfo* texture_info = 5155 texture_unit.GetInfoForSamplerType(uniform_info->type); 5156 if (texture_info && !texture_info->SafeToRenderFrom()) { 5157 if (!texture_manager()->ClearRenderableLevels(this, texture_info)) { 5158 return false; 5159 } 5160 } 5161 } 5162 } 5163 } 5164 } 5165 return true; 5166} 5167 5168bool GLES2DecoderImpl::IsDrawValid( 5169 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) { 5170 // NOTE: We specifically do not check current_program->IsValid() because 5171 // it could never be invalid since glUseProgram would have failed. While 5172 // glLinkProgram could later mark the program as invalid the previous 5173 // valid program will still function if it is still the current program. 5174 if (!state_.current_program) { 5175 // The program does not exist. 5176 // But GL says no ERROR. 5177 RenderWarning("Drawing with no current shader program."); 5178 return false; 5179 } 5180 5181 // true if any enabled, used divisor is zero 5182 bool divisor0 = false; 5183 // Validate all attribs currently enabled. If they are used by the current 5184 // program then check that they have enough elements to handle the draw call. 5185 // If they are not used by the current program check that they have a buffer 5186 // assigned. 5187 const VertexAttribManager::VertexAttribInfoList& infos = 5188 state_.vertex_attrib_manager->GetEnabledVertexAttribInfos(); 5189 for (VertexAttribManager::VertexAttribInfoList::const_iterator it = 5190 infos.begin(); it != infos.end(); ++it) { 5191 const VertexAttribManager::VertexAttribInfo* info = *it; 5192 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = 5193 state_.current_program->GetAttribInfoByLocation(info->index()); 5194 if (attrib_info) { 5195 divisor0 |= (info->divisor() == 0); 5196 GLuint count = info->MaxVertexAccessed(primcount, max_vertex_accessed); 5197 // This attrib is used in the current program. 5198 if (!info->CanAccess(count)) { 5199 SetGLError( 5200 GL_INVALID_OPERATION, function_name, 5201 (std::string( 5202 "attempt to access out of range vertices in attribute ") + 5203 base::IntToString(info->index())).c_str()); 5204 return false; 5205 } 5206 } else { 5207 // This attrib is not used in the current program. 5208 if (!info->buffer()) { 5209 SetGLError( 5210 GL_INVALID_OPERATION, function_name, 5211 (std::string( 5212 "attempt to render with no buffer attached to " 5213 "enabled attribute ") + 5214 base::IntToString(info->index())).c_str()); 5215 return false; 5216 } 5217 } 5218 } 5219 5220 if (primcount && !divisor0) { 5221 SetGLError( 5222 GL_INVALID_OPERATION, function_name, 5223 "attempt instanced render with all attributes having " 5224 "non-zero divisors"); 5225 return false; 5226 } 5227 5228 return true; 5229} 5230 5231bool GLES2DecoderImpl::SimulateAttrib0( 5232 const char* function_name, GLuint max_vertex_accessed, bool* simulated) { 5233 DCHECK(simulated); 5234 *simulated = false; 5235 5236 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) 5237 return true; 5238 5239 const VertexAttribManager::VertexAttribInfo* info = 5240 state_.vertex_attrib_manager->GetVertexAttribInfo(0); 5241 // If it's enabled or it's not used then we don't need to do anything. 5242 bool attrib_0_used = 5243 state_.current_program->GetAttribInfoByLocation(0) != NULL; 5244 if (info->enabled() && attrib_0_used) { 5245 return true; 5246 } 5247 5248 // Make a buffer with a single repeated vec4 value enough to 5249 // simulate the constant value that is supposed to be here. 5250 // This is required to emulate GLES2 on GL. 5251 typedef VertexAttribManager::VertexAttribInfo::Vec4 Vec4; 5252 5253 GLuint num_vertices = max_vertex_accessed + 1; 5254 uint32 size_needed = 0; 5255 5256 if (num_vertices == 0 || 5257 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) || 5258 size_needed > 0x7FFFFFFFU) { 5259 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); 5260 return false; 5261 } 5262 5263 PerformanceWarning( 5264 "Attribute 0 is disabled. This has signficant performance penalty"); 5265 5266 CopyRealGLErrorsToWrapper(); 5267 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_); 5268 5269 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_; 5270 if (new_buffer) { 5271 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); 5272 GLenum error = glGetError(); 5273 if (error != GL_NO_ERROR) { 5274 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); 5275 return false; 5276 } 5277 } 5278 if (new_buffer || 5279 (attrib_0_used && 5280 (!attrib_0_buffer_matches_value_ || 5281 (info->value().v[0] != attrib_0_value_.v[0] || 5282 info->value().v[1] != attrib_0_value_.v[1] || 5283 info->value().v[2] != attrib_0_value_.v[2] || 5284 info->value().v[3] != attrib_0_value_.v[3])))) { 5285 std::vector<Vec4> temp(num_vertices, info->value()); 5286 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]); 5287 attrib_0_buffer_matches_value_ = true; 5288 attrib_0_value_ = info->value(); 5289 attrib_0_size_ = size_needed; 5290 } 5291 5292 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); 5293 5294 if (info->divisor()) 5295 glVertexAttribDivisorANGLE(0, 0); 5296 5297 *simulated = true; 5298 return true; 5299} 5300 5301void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib) { 5302 const VertexAttribManager::VertexAttribInfo* info = 5303 state_.vertex_attrib_manager->GetVertexAttribInfo(attrib); 5304 const void* ptr = reinterpret_cast<const void*>(info->offset()); 5305 BufferManager::BufferInfo* buffer_info = info->buffer(); 5306 glBindBuffer(GL_ARRAY_BUFFER, buffer_info ? buffer_info->service_id() : 0); 5307 glVertexAttribPointer( 5308 attrib, info->size(), info->type(), info->normalized(), info->gl_stride(), 5309 ptr); 5310 if (info->divisor()) 5311 glVertexAttribDivisorANGLE(attrib, info->divisor()); 5312 glBindBuffer( 5313 GL_ARRAY_BUFFER, 5314 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0); 5315 5316 // Never touch vertex attribute 0's state (in particular, never 5317 // disable it) when running on desktop GL because it will never be 5318 // re-enabled. 5319 if (attrib != 0 || 5320 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) { 5321 if (info->enabled()) { 5322 glEnableVertexAttribArray(attrib); 5323 } else { 5324 glDisableVertexAttribArray(attrib); 5325 } 5326 } 5327} 5328 5329bool GLES2DecoderImpl::SimulateFixedAttribs( 5330 const char* function_name, 5331 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) { 5332 DCHECK(simulated); 5333 *simulated = false; 5334 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) 5335 return true; 5336 5337 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) { 5338 return true; 5339 } 5340 5341 PerformanceWarning( 5342 "GL_FIXED attributes have a signficant performance penalty"); 5343 5344 // NOTE: we could be smart and try to check if a buffer is used 5345 // twice in 2 different attribs, find the overlapping parts and therefore 5346 // duplicate the minimum amount of data but this whole code path is not meant 5347 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance 5348 // tests so we just add to the buffer attrib used. 5349 5350 GLuint elements_needed = 0; 5351 const VertexAttribManager::VertexAttribInfoList& infos = 5352 state_.vertex_attrib_manager->GetEnabledVertexAttribInfos(); 5353 for (VertexAttribManager::VertexAttribInfoList::const_iterator it = 5354 infos.begin(); it != infos.end(); ++it) { 5355 const VertexAttribManager::VertexAttribInfo* info = *it; 5356 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = 5357 state_.current_program->GetAttribInfoByLocation(info->index()); 5358 GLuint max_accessed = info->MaxVertexAccessed(primcount, 5359 max_vertex_accessed); 5360 GLuint num_vertices = max_accessed + 1; 5361 if (num_vertices == 0) { 5362 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); 5363 return false; 5364 } 5365 if (attrib_info && 5366 info->CanAccess(max_accessed) && 5367 info->type() == GL_FIXED) { 5368 uint32 elements_used = 0; 5369 if (!SafeMultiplyUint32(num_vertices, info->size(), &elements_used) || 5370 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) { 5371 SetGLError( 5372 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs"); 5373 return false; 5374 } 5375 } 5376 } 5377 5378 const uint32 kSizeOfFloat = sizeof(float); // NOLINT 5379 uint32 size_needed = 0; 5380 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) || 5381 size_needed > 0x7FFFFFFFU) { 5382 SetGLError(GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs"); 5383 return false; 5384 } 5385 5386 CopyRealGLErrorsToWrapper(); 5387 5388 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_); 5389 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) { 5390 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW); 5391 GLenum error = glGetError(); 5392 if (error != GL_NO_ERROR) { 5393 SetGLError( 5394 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs"); 5395 return false; 5396 } 5397 } 5398 5399 // Copy the elements and convert to float 5400 GLintptr offset = 0; 5401 for (VertexAttribManager::VertexAttribInfoList::const_iterator it = 5402 infos.begin(); it != infos.end(); ++it) { 5403 const VertexAttribManager::VertexAttribInfo* info = *it; 5404 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = 5405 state_.current_program->GetAttribInfoByLocation(info->index()); 5406 GLuint max_accessed = info->MaxVertexAccessed(primcount, 5407 max_vertex_accessed); 5408 GLuint num_vertices = max_accessed + 1; 5409 if (num_vertices == 0) { 5410 SetGLError(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0"); 5411 return false; 5412 } 5413 if (attrib_info && 5414 info->CanAccess(max_accessed) && 5415 info->type() == GL_FIXED) { 5416 int num_elements = info->size() * kSizeOfFloat; 5417 int size = num_elements * num_vertices; 5418 scoped_array<float> data(new float[size]); 5419 const int32* src = reinterpret_cast<const int32 *>( 5420 info->buffer()->GetRange(info->offset(), size)); 5421 const int32* end = src + num_elements; 5422 float* dst = data.get(); 5423 while (src != end) { 5424 *dst++ = static_cast<float>(*src++) / 65536.0f; 5425 } 5426 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get()); 5427 glVertexAttribPointer( 5428 info->index(), info->size(), GL_FLOAT, false, 0, 5429 reinterpret_cast<GLvoid*>(offset)); 5430 offset += size; 5431 } 5432 } 5433 *simulated = true; 5434 return true; 5435} 5436 5437void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() { 5438 // There's no need to call glVertexAttribPointer because we shadow all the 5439 // settings and passing GL_FIXED to it will not work. 5440 glBindBuffer( 5441 GL_ARRAY_BUFFER, 5442 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0); 5443} 5444 5445error::Error GLES2DecoderImpl::DoDrawArrays( 5446 const char* function_name, 5447 bool instanced, 5448 GLenum mode, 5449 GLint first, 5450 GLsizei count, 5451 GLsizei primcount) { 5452 if (ShouldDeferDraws()) 5453 return error::kDeferCommandUntilLater; 5454 if (!validators_->draw_mode.IsValid(mode)) { 5455 SetGLErrorInvalidEnum(function_name, mode, "mode"); 5456 return error::kNoError; 5457 } 5458 if (count < 0) { 5459 SetGLError(GL_INVALID_VALUE, function_name, "count < 0"); 5460 return error::kNoError; 5461 } 5462 if (primcount < 0) { 5463 SetGLError(GL_INVALID_VALUE, function_name, "primcount < 0"); 5464 return error::kNoError; 5465 } 5466 if (!CheckBoundFramebuffersValid(function_name)) { 5467 return error::kNoError; 5468 } 5469 // We have to check this here because the prototype for glDrawArrays 5470 // is GLint not GLsizei. 5471 if (first < 0) { 5472 SetGLError(GL_INVALID_VALUE, function_name, "first < 0"); 5473 return error::kNoError; 5474 } 5475 5476 if (count == 0 || (instanced && primcount == 0)) { 5477 RenderWarning("Render count or primcount is 0."); 5478 return error::kNoError; 5479 } 5480 5481 GLuint max_vertex_accessed = first + count - 1; 5482 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) { 5483 if (!ClearUnclearedTextures()) { 5484 SetGLError(GL_INVALID_VALUE, function_name, "out of memory"); 5485 return error::kNoError; 5486 } 5487 bool simulated_attrib_0 = false; 5488 if (!SimulateAttrib0( 5489 function_name, max_vertex_accessed, &simulated_attrib_0)) { 5490 return error::kNoError; 5491 } 5492 bool simulated_fixed_attribs = false; 5493 if (SimulateFixedAttribs( 5494 function_name, max_vertex_accessed, &simulated_fixed_attribs, 5495 primcount)) { 5496 bool textures_set = SetBlackTextureForNonRenderableTextures(); 5497 ApplyDirtyState(); 5498 if (!instanced) { 5499 glDrawArrays(mode, first, count); 5500 } else { 5501 glDrawArraysInstancedANGLE(mode, first, count, primcount); 5502 } 5503 ProcessPendingQueries(); 5504 if (textures_set) { 5505 RestoreStateForNonRenderableTextures(); 5506 } 5507 if (simulated_fixed_attribs) { 5508 RestoreStateForSimulatedFixedAttribs(); 5509 } 5510 } 5511 if (simulated_attrib_0) { 5512 RestoreStateForAttrib(0); 5513 } 5514 if (WasContextLost()) { 5515 LOG(ERROR) << " GLES2DecoderImpl: Context lost during DrawArrays."; 5516 return error::kLostContext; 5517 } 5518 } 5519 return error::kNoError; 5520} 5521 5522error::Error GLES2DecoderImpl::HandleDrawArrays( 5523 uint32 immediate_data_size, const gles2::DrawArrays& c) { 5524 return DoDrawArrays("glDrawArrays", 5525 false, 5526 static_cast<GLenum>(c.mode), 5527 static_cast<GLint>(c.first), 5528 static_cast<GLsizei>(c.count), 5529 0); 5530} 5531 5532error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE( 5533 uint32 immediate_data_size, const gles2::DrawArraysInstancedANGLE& c) { 5534 if (!features().angle_instanced_arrays) { 5535 SetGLError(GL_INVALID_OPERATION, 5536 "glDrawArraysInstancedANGLE", "function not available"); 5537 return error::kNoError; 5538 } 5539 return DoDrawArrays("glDrawArraysIntancedANGLE", 5540 true, 5541 static_cast<GLenum>(c.mode), 5542 static_cast<GLint>(c.first), 5543 static_cast<GLsizei>(c.count), 5544 static_cast<GLsizei>(c.primcount)); 5545} 5546 5547error::Error GLES2DecoderImpl::DoDrawElements( 5548 const char* function_name, 5549 bool instanced, 5550 GLenum mode, 5551 GLsizei count, 5552 GLenum type, 5553 int32 offset, 5554 GLsizei primcount) { 5555 if (ShouldDeferDraws()) 5556 return error::kDeferCommandUntilLater; 5557 if (!state_.vertex_attrib_manager->element_array_buffer()) { 5558 SetGLError(GL_INVALID_OPERATION, 5559 function_name, "No element array buffer bound"); 5560 return error::kNoError; 5561 } 5562 5563 if (count < 0) { 5564 SetGLError(GL_INVALID_VALUE, function_name, "count < 0"); 5565 return error::kNoError; 5566 } 5567 if (offset < 0) { 5568 SetGLError(GL_INVALID_VALUE, function_name, "offset < 0"); 5569 return error::kNoError; 5570 } 5571 if (!validators_->draw_mode.IsValid(mode)) { 5572 SetGLErrorInvalidEnum(function_name, mode, "mode"); 5573 return error::kNoError; 5574 } 5575 if (!validators_->index_type.IsValid(type)) { 5576 SetGLErrorInvalidEnum(function_name, type, "type"); 5577 return error::kNoError; 5578 } 5579 if (primcount < 0) { 5580 SetGLError(GL_INVALID_VALUE, function_name, "primcount < 0"); 5581 return error::kNoError; 5582 } 5583 5584 if (!CheckBoundFramebuffersValid(function_name)) { 5585 return error::kNoError; 5586 } 5587 5588 if (count == 0 || (instanced && primcount == 0)) { 5589 return error::kNoError; 5590 } 5591 5592 GLuint max_vertex_accessed; 5593 if (!state_.vertex_attrib_manager->element_array_buffer( 5594 )->GetMaxValueForRange(offset, count, type, &max_vertex_accessed)) { 5595 SetGLError(GL_INVALID_OPERATION, 5596 function_name, "range out of bounds for buffer"); 5597 return error::kNoError; 5598 } 5599 5600 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) { 5601 if (!ClearUnclearedTextures()) { 5602 SetGLError(GL_INVALID_VALUE, function_name, "out of memory"); 5603 return error::kNoError; 5604 } 5605 bool simulated_attrib_0 = false; 5606 if (!SimulateAttrib0( 5607 function_name, max_vertex_accessed, &simulated_attrib_0)) { 5608 return error::kNoError; 5609 } 5610 bool simulated_fixed_attribs = false; 5611 if (SimulateFixedAttribs( 5612 function_name, max_vertex_accessed, &simulated_fixed_attribs, 5613 primcount)) { 5614 bool textures_set = SetBlackTextureForNonRenderableTextures(); 5615 ApplyDirtyState(); 5616 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); 5617 if (!instanced) { 5618 glDrawElements(mode, count, type, indices); 5619 } else { 5620 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount); 5621 } 5622 ProcessPendingQueries(); 5623 if (textures_set) { 5624 RestoreStateForNonRenderableTextures(); 5625 } 5626 if (simulated_fixed_attribs) { 5627 RestoreStateForSimulatedFixedAttribs(); 5628 } 5629 } 5630 if (simulated_attrib_0) { 5631 RestoreStateForAttrib(0); 5632 } 5633 if (WasContextLost()) { 5634 LOG(ERROR) << " GLES2DecoderImpl: Context lost during DrawElements."; 5635 return error::kLostContext; 5636 } 5637 } 5638 return error::kNoError; 5639} 5640 5641error::Error GLES2DecoderImpl::HandleDrawElements( 5642 uint32 immediate_data_size, const gles2::DrawElements& c) { 5643 return DoDrawElements("glDrawElements", 5644 false, 5645 static_cast<GLenum>(c.mode), 5646 static_cast<GLsizei>(c.count), 5647 static_cast<GLenum>(c.type), 5648 static_cast<int32>(c.index_offset), 5649 0); 5650} 5651 5652error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE( 5653 uint32 immediate_data_size, const gles2::DrawElementsInstancedANGLE& c) { 5654 if (!features().angle_instanced_arrays) { 5655 SetGLError(GL_INVALID_OPERATION, 5656 "glDrawElementsInstancedANGLE", "function not available"); 5657 return error::kNoError; 5658 } 5659 return DoDrawElements("glDrawElementsInstancedANGLE", 5660 true, 5661 static_cast<GLenum>(c.mode), 5662 static_cast<GLsizei>(c.count), 5663 static_cast<GLenum>(c.type), 5664 static_cast<int32>(c.index_offset), 5665 static_cast<GLsizei>(c.primcount)); 5666} 5667 5668GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM( 5669 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) { 5670 GLuint max_vertex_accessed = 0; 5671 BufferManager::BufferInfo* info = GetBufferInfo(buffer_id); 5672 if (!info) { 5673 // TODO(gman): Should this be a GL error or a command buffer error? 5674 SetGLError(GL_INVALID_VALUE, 5675 "GetMaxValueInBufferCHROMIUM", "unknown buffer"); 5676 } else { 5677 if (!info->GetMaxValueForRange(offset, count, type, &max_vertex_accessed)) { 5678 // TODO(gman): Should this be a GL error or a command buffer error? 5679 SetGLError( 5680 GL_INVALID_OPERATION, 5681 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer"); 5682 } 5683 } 5684 return max_vertex_accessed; 5685} 5686 5687// Calls glShaderSource for the various versions of the ShaderSource command. 5688// Assumes that data / data_size points to a piece of memory that is in range 5689// of whatever context it came from (shared memory, immediate memory, bucket 5690// memory.) 5691error::Error GLES2DecoderImpl::ShaderSourceHelper( 5692 GLuint client_id, const char* data, uint32 data_size) { 5693 std::string str(data, data + data_size); 5694 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram( 5695 client_id, "glShaderSource"); 5696 if (!info) { 5697 return error::kNoError; 5698 } 5699 // Note: We don't actually call glShaderSource here. We wait until 5700 // the call to glCompileShader. 5701 info->UpdateSource(str.c_str()); 5702 return error::kNoError; 5703} 5704 5705error::Error GLES2DecoderImpl::HandleShaderSource( 5706 uint32 immediate_data_size, const gles2::ShaderSource& c) { 5707 uint32 data_size = c.data_size; 5708 const char* data = GetSharedMemoryAs<const char*>( 5709 c.data_shm_id, c.data_shm_offset, data_size); 5710 if (!data) { 5711 return error::kOutOfBounds; 5712 } 5713 return ShaderSourceHelper(c.shader, data, data_size); 5714} 5715 5716error::Error GLES2DecoderImpl::HandleShaderSourceImmediate( 5717 uint32 immediate_data_size, const gles2::ShaderSourceImmediate& c) { 5718 uint32 data_size = c.data_size; 5719 const char* data = GetImmediateDataAs<const char*>( 5720 c, data_size, immediate_data_size); 5721 if (!data) { 5722 return error::kOutOfBounds; 5723 } 5724 return ShaderSourceHelper(c.shader, data, data_size); 5725} 5726 5727error::Error GLES2DecoderImpl::HandleShaderSourceBucket( 5728 uint32 immediate_data_size, const gles2::ShaderSourceBucket& c) { 5729 Bucket* bucket = GetBucket(c.data_bucket_id); 5730 if (!bucket || bucket->size() == 0) { 5731 return error::kInvalidArguments; 5732 } 5733 return ShaderSourceHelper( 5734 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1), 5735 bucket->size() - 1); 5736} 5737 5738void GLES2DecoderImpl::DoCompileShader(GLuint client_id) { 5739 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader"); 5740 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram( 5741 client_id, "glCompileShader"); 5742 if (!info) { 5743 return; 5744 } 5745 ShaderTranslator* translator = NULL; 5746 if (use_shader_translator_) { 5747 translator = info->shader_type() == GL_VERTEX_SHADER ? 5748 vertex_translator_.get() : fragment_translator_.get(); 5749 } 5750 5751 program_manager()->DoCompileShader(info, translator, feature_info_); 5752}; 5753 5754void GLES2DecoderImpl::DoGetShaderiv( 5755 GLuint shader, GLenum pname, GLint* params) { 5756 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram( 5757 shader, "glGetShaderiv"); 5758 if (!info) { 5759 return; 5760 } 5761 switch (pname) { 5762 case GL_SHADER_SOURCE_LENGTH: 5763 *params = info->source() ? info->source()->size() + 1 : 0; 5764 return; 5765 case GL_COMPILE_STATUS: 5766 *params = compile_shader_always_succeeds_ ? true : info->IsValid(); 5767 return; 5768 case GL_INFO_LOG_LENGTH: 5769 *params = info->log_info() ? info->log_info()->size() + 1 : 0; 5770 return; 5771 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: 5772 ForceCompileShaderIfPending(info); 5773 *params = info->translated_source() ? 5774 info->translated_source()->size() + 1 : 0; 5775 return; 5776 default: 5777 break; 5778 } 5779 glGetShaderiv(info->service_id(), pname, params); 5780} 5781 5782error::Error GLES2DecoderImpl::HandleGetShaderSource( 5783 uint32 immediate_data_size, const gles2::GetShaderSource& c) { 5784 GLuint shader = c.shader; 5785 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 5786 Bucket* bucket = CreateBucket(bucket_id); 5787 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram( 5788 shader, "glGetShaderSource"); 5789 if (!info || !info->source()) { 5790 bucket->SetSize(0); 5791 return error::kNoError; 5792 } 5793 bucket->SetFromString(info->source()->c_str()); 5794 return error::kNoError; 5795} 5796 5797error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE( 5798 uint32 immediate_data_size, 5799 const gles2::GetTranslatedShaderSourceANGLE& c) { 5800 GLuint shader = c.shader; 5801 5802 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 5803 Bucket* bucket = CreateBucket(bucket_id); 5804 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram( 5805 shader, "glTranslatedGetShaderSourceANGLE"); 5806 if (!info) { 5807 bucket->SetSize(0); 5808 return error::kNoError; 5809 } 5810 ForceCompileShaderIfPending(info); 5811 5812 bucket->SetFromString(info->translated_source() ? 5813 info->translated_source()->c_str() : NULL); 5814 return error::kNoError; 5815} 5816 5817error::Error GLES2DecoderImpl::HandleGetProgramInfoLog( 5818 uint32 immediate_data_size, const gles2::GetProgramInfoLog& c) { 5819 GLuint program = c.program; 5820 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 5821 Bucket* bucket = CreateBucket(bucket_id); 5822 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( 5823 program, "glGetProgramInfoLog"); 5824 if (!info || !info->log_info()) { 5825 bucket->SetFromString(""); 5826 return error::kNoError; 5827 } 5828 bucket->SetFromString(info->log_info()->c_str()); 5829 return error::kNoError; 5830} 5831 5832error::Error GLES2DecoderImpl::HandleGetShaderInfoLog( 5833 uint32 immediate_data_size, const gles2::GetShaderInfoLog& c) { 5834 GLuint shader = c.shader; 5835 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 5836 Bucket* bucket = CreateBucket(bucket_id); 5837 ShaderManager::ShaderInfo* info = GetShaderInfoNotProgram( 5838 shader, "glGetShaderInfoLog"); 5839 if (!info || !info->log_info()) { 5840 bucket->SetFromString(""); 5841 return error::kNoError; 5842 } 5843 bucket->SetFromString(info->log_info()->c_str()); 5844 return error::kNoError; 5845} 5846 5847bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) { 5848 const BufferManager::BufferInfo* buffer = GetBufferInfo(client_id); 5849 return buffer && buffer->IsValid() && !buffer->IsDeleted(); 5850} 5851 5852bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) { 5853 const FramebufferManager::FramebufferInfo* framebuffer = 5854 GetFramebufferInfo(client_id); 5855 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted(); 5856} 5857 5858bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) { 5859 // IsProgram is true for programs as soon as they are created, until they are 5860 // deleted and no longer in use. 5861 const ProgramManager::ProgramInfo* program = GetProgramInfo(client_id); 5862 return program != NULL && !program->IsDeleted(); 5863} 5864 5865bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) { 5866 const RenderbufferManager::RenderbufferInfo* renderbuffer = 5867 GetRenderbufferInfo(client_id); 5868 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted(); 5869} 5870 5871bool GLES2DecoderImpl::DoIsShader(GLuint client_id) { 5872 // IsShader is true for shaders as soon as they are created, until they 5873 // are deleted and not attached to any programs. 5874 const ShaderManager::ShaderInfo* shader = GetShaderInfo(client_id); 5875 return shader != NULL && !shader->IsDeleted(); 5876} 5877 5878bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) { 5879 const TextureManager::TextureInfo* texture = GetTextureInfo(client_id); 5880 return texture && texture->IsValid() && !texture->IsDeleted(); 5881} 5882 5883void GLES2DecoderImpl::DoAttachShader( 5884 GLuint program_client_id, GLint shader_client_id) { 5885 ProgramManager::ProgramInfo* program_info = GetProgramInfoNotShader( 5886 program_client_id, "glAttachShader"); 5887 if (!program_info) { 5888 return; 5889 } 5890 ShaderManager::ShaderInfo* shader_info = GetShaderInfoNotProgram( 5891 shader_client_id, "glAttachShader"); 5892 if (!shader_info) { 5893 return; 5894 } 5895 if (!program_info->AttachShader(shader_manager(), shader_info)) { 5896 SetGLError(GL_INVALID_OPERATION, 5897 "glAttachShader", "can not attach more than" 5898 " one shader of the same type."); 5899 return; 5900 } 5901 glAttachShader(program_info->service_id(), shader_info->service_id()); 5902} 5903 5904void GLES2DecoderImpl::DoDetachShader( 5905 GLuint program_client_id, GLint shader_client_id) { 5906 ProgramManager::ProgramInfo* program_info = GetProgramInfoNotShader( 5907 program_client_id, "glDetachShader"); 5908 if (!program_info) { 5909 return; 5910 } 5911 ShaderManager::ShaderInfo* shader_info = GetShaderInfoNotProgram( 5912 shader_client_id, "glDetachShader"); 5913 if (!shader_info) { 5914 return; 5915 } 5916 if (!program_info->DetachShader(shader_manager(), shader_info)) { 5917 SetGLError(GL_INVALID_OPERATION, 5918 "glDetachShader", "shader not attached to program"); 5919 return; 5920 } 5921 glDetachShader(program_info->service_id(), shader_info->service_id()); 5922} 5923 5924void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) { 5925 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( 5926 program_client_id, "glValidateProgram"); 5927 if (!info) { 5928 return; 5929 } 5930 info->Validate(); 5931} 5932 5933void GLES2DecoderImpl::DoGetVertexAttribfv( 5934 GLuint index, GLenum pname, GLfloat* params) { 5935 VertexAttribManager::VertexAttribInfo* info = 5936 state_.vertex_attrib_manager->GetVertexAttribInfo(index); 5937 if (!info) { 5938 SetGLError(GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range"); 5939 return; 5940 } 5941 switch (pname) { 5942 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: { 5943 BufferManager::BufferInfo* buffer = info->buffer(); 5944 if (buffer && !buffer->IsDeleted()) { 5945 GLuint client_id; 5946 buffer_manager()->GetClientId(buffer->service_id(), &client_id); 5947 *params = static_cast<GLfloat>(client_id); 5948 } 5949 break; 5950 } 5951 case GL_VERTEX_ATTRIB_ARRAY_ENABLED: 5952 *params = static_cast<GLfloat>(info->enabled()); 5953 break; 5954 case GL_VERTEX_ATTRIB_ARRAY_SIZE: 5955 *params = static_cast<GLfloat>(info->size()); 5956 break; 5957 case GL_VERTEX_ATTRIB_ARRAY_STRIDE: 5958 *params = static_cast<GLfloat>(info->gl_stride()); 5959 break; 5960 case GL_VERTEX_ATTRIB_ARRAY_TYPE: 5961 *params = static_cast<GLfloat>(info->type()); 5962 break; 5963 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: 5964 *params = static_cast<GLfloat>(info->normalized()); 5965 break; 5966 case GL_CURRENT_VERTEX_ATTRIB: 5967 params[0] = info->value().v[0]; 5968 params[1] = info->value().v[1]; 5969 params[2] = info->value().v[2]; 5970 params[3] = info->value().v[3]; 5971 break; 5972 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: 5973 *params = static_cast<GLfloat>(info->divisor()); 5974 break; 5975 default: 5976 NOTREACHED(); 5977 break; 5978 } 5979} 5980 5981void GLES2DecoderImpl::DoGetVertexAttribiv( 5982 GLuint index, GLenum pname, GLint* params) { 5983 VertexAttribManager::VertexAttribInfo* info = 5984 state_.vertex_attrib_manager->GetVertexAttribInfo(index); 5985 if (!info) { 5986 SetGLError(GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range"); 5987 return; 5988 } 5989 switch (pname) { 5990 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: { 5991 BufferManager::BufferInfo* buffer = info->buffer(); 5992 if (buffer && !buffer->IsDeleted()) { 5993 GLuint client_id; 5994 buffer_manager()->GetClientId(buffer->service_id(), &client_id); 5995 *params = client_id; 5996 } 5997 break; 5998 } 5999 case GL_VERTEX_ATTRIB_ARRAY_ENABLED: 6000 *params = info->enabled(); 6001 break; 6002 case GL_VERTEX_ATTRIB_ARRAY_SIZE: 6003 *params = info->size(); 6004 break; 6005 case GL_VERTEX_ATTRIB_ARRAY_STRIDE: 6006 *params = info->gl_stride(); 6007 break; 6008 case GL_VERTEX_ATTRIB_ARRAY_TYPE: 6009 *params = info->type(); 6010 break; 6011 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: 6012 *params = static_cast<GLint>(info->normalized()); 6013 break; 6014 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: 6015 *params = info->divisor(); 6016 break; 6017 case GL_CURRENT_VERTEX_ATTRIB: 6018 params[0] = static_cast<GLint>(info->value().v[0]); 6019 params[1] = static_cast<GLint>(info->value().v[1]); 6020 params[2] = static_cast<GLint>(info->value().v[2]); 6021 params[3] = static_cast<GLint>(info->value().v[3]); 6022 break; 6023 default: 6024 NOTREACHED(); 6025 break; 6026 } 6027} 6028 6029void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) { 6030 VertexAttribManager::VertexAttribInfo* info = 6031 state_.vertex_attrib_manager->GetVertexAttribInfo(index); 6032 if (!info) { 6033 SetGLError(GL_INVALID_VALUE, "glVertexAttrib1f", "index out of range"); 6034 return; 6035 } 6036 VertexAttribManager::VertexAttribInfo::Vec4 value; 6037 value.v[0] = v0; 6038 value.v[1] = 0.0f; 6039 value.v[2] = 0.0f; 6040 value.v[3] = 1.0f; 6041 info->set_value(value); 6042 glVertexAttrib1f(index, v0); 6043} 6044 6045void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) { 6046 VertexAttribManager::VertexAttribInfo* info = 6047 state_.vertex_attrib_manager->GetVertexAttribInfo(index); 6048 if (!info) { 6049 SetGLError(GL_INVALID_VALUE, "glVertexAttrib2f", "index out of range"); 6050 return; 6051 } 6052 VertexAttribManager::VertexAttribInfo::Vec4 value; 6053 value.v[0] = v0; 6054 value.v[1] = v1; 6055 value.v[2] = 0.0f; 6056 value.v[3] = 1.0f; 6057 info->set_value(value); 6058 glVertexAttrib2f(index, v0, v1); 6059} 6060 6061void GLES2DecoderImpl::DoVertexAttrib3f( 6062 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) { 6063 VertexAttribManager::VertexAttribInfo* info = 6064 state_.vertex_attrib_manager->GetVertexAttribInfo(index); 6065 if (!info) { 6066 SetGLError(GL_INVALID_VALUE, "glVertexAttrib3f", "index out of range"); 6067 return; 6068 } 6069 VertexAttribManager::VertexAttribInfo::Vec4 value; 6070 value.v[0] = v0; 6071 value.v[1] = v1; 6072 value.v[2] = v2; 6073 value.v[3] = 1.0f; 6074 info->set_value(value); 6075 glVertexAttrib3f(index, v0, v1, v2); 6076} 6077 6078void GLES2DecoderImpl::DoVertexAttrib4f( 6079 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) { 6080 VertexAttribManager::VertexAttribInfo* info = 6081 state_.vertex_attrib_manager->GetVertexAttribInfo(index); 6082 if (!info) { 6083 SetGLError(GL_INVALID_VALUE, "glVertexAttrib4f", "index out of range"); 6084 return; 6085 } 6086 VertexAttribManager::VertexAttribInfo::Vec4 value; 6087 value.v[0] = v0; 6088 value.v[1] = v1; 6089 value.v[2] = v2; 6090 value.v[3] = v3; 6091 info->set_value(value); 6092 glVertexAttrib4f(index, v0, v1, v2, v3); 6093} 6094 6095void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) { 6096 VertexAttribManager::VertexAttribInfo* info = 6097 state_.vertex_attrib_manager->GetVertexAttribInfo(index); 6098 if (!info) { 6099 SetGLError(GL_INVALID_VALUE, "glVertexAttrib1fv", "index out of range"); 6100 return; 6101 } 6102 VertexAttribManager::VertexAttribInfo::Vec4 value; 6103 value.v[0] = v[0]; 6104 value.v[1] = 0.0f; 6105 value.v[2] = 0.0f; 6106 value.v[3] = 1.0f; 6107 info->set_value(value); 6108 glVertexAttrib1fv(index, v); 6109} 6110 6111void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) { 6112 VertexAttribManager::VertexAttribInfo* info = 6113 state_.vertex_attrib_manager->GetVertexAttribInfo(index); 6114 if (!info) { 6115 SetGLError(GL_INVALID_VALUE, "glVertexAttrib2fv", "index out of range"); 6116 return; 6117 } 6118 VertexAttribManager::VertexAttribInfo::Vec4 value; 6119 value.v[0] = v[0]; 6120 value.v[1] = v[1]; 6121 value.v[2] = 0.0f; 6122 value.v[3] = 1.0f; 6123 info->set_value(value); 6124 glVertexAttrib2fv(index, v); 6125} 6126 6127void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) { 6128 VertexAttribManager::VertexAttribInfo* info = 6129 state_.vertex_attrib_manager->GetVertexAttribInfo(index); 6130 if (!info) { 6131 SetGLError(GL_INVALID_VALUE, "glVertexAttrib3fv", "index out of range"); 6132 return; 6133 } 6134 VertexAttribManager::VertexAttribInfo::Vec4 value; 6135 value.v[0] = v[0]; 6136 value.v[1] = v[1]; 6137 value.v[2] = v[2]; 6138 value.v[3] = 1.0f; 6139 info->set_value(value); 6140 glVertexAttrib3fv(index, v); 6141} 6142 6143void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) { 6144 VertexAttribManager::VertexAttribInfo* info = 6145 state_.vertex_attrib_manager->GetVertexAttribInfo(index); 6146 if (!info) { 6147 SetGLError(GL_INVALID_VALUE, "glVertexAttrib4fv", "index out of range"); 6148 return; 6149 } 6150 VertexAttribManager::VertexAttribInfo::Vec4 value; 6151 value.v[0] = v[0]; 6152 value.v[1] = v[1]; 6153 value.v[2] = v[2]; 6154 value.v[3] = v[3]; 6155 info->set_value(value); 6156 glVertexAttrib4fv(index, v); 6157} 6158 6159error::Error GLES2DecoderImpl::HandleVertexAttribPointer( 6160 uint32 immediate_data_size, const gles2::VertexAttribPointer& c) { 6161 6162 if (!state_.bound_array_buffer || state_.bound_array_buffer->IsDeleted()) { 6163 if (state_.vertex_attrib_manager == default_vertex_attrib_manager_) { 6164 SetGLError(GL_INVALID_VALUE, 6165 "glVertexAttribPointer", "no array buffer bound"); 6166 return error::kNoError; 6167 } else if (c.offset != 0) { 6168 SetGLError(GL_INVALID_VALUE, 6169 "glVertexAttribPointer", "client side arrays are not allowed"); 6170 return error::kNoError; 6171 } 6172 } 6173 6174 GLuint indx = c.indx; 6175 GLint size = c.size; 6176 GLenum type = c.type; 6177 GLboolean normalized = c.normalized; 6178 GLsizei stride = c.stride; 6179 GLsizei offset = c.offset; 6180 const void* ptr = reinterpret_cast<const void*>(offset); 6181 if (!validators_->vertex_attrib_type.IsValid(type)) { 6182 SetGLErrorInvalidEnum("glVertexAttribPointer", type, "type"); 6183 return error::kNoError; 6184 } 6185 if (!validators_->vertex_attrib_size.IsValid(size)) { 6186 SetGLError(GL_INVALID_VALUE, 6187 "glVertexAttribPointer", "size GL_INVALID_VALUE"); 6188 return error::kNoError; 6189 } 6190 if (indx >= group_->max_vertex_attribs()) { 6191 SetGLError(GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range"); 6192 return error::kNoError; 6193 } 6194 if (stride < 0) { 6195 SetGLError(GL_INVALID_VALUE, 6196 "glVertexAttribPointer", "stride < 0"); 6197 return error::kNoError; 6198 } 6199 if (stride > 255) { 6200 SetGLError(GL_INVALID_VALUE, 6201 "glVertexAttribPointer", "stride > 255"); 6202 return error::kNoError; 6203 } 6204 if (offset < 0) { 6205 SetGLError(GL_INVALID_VALUE, 6206 "glVertexAttribPointer", "offset < 0"); 6207 return error::kNoError; 6208 } 6209 GLsizei component_size = 6210 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type); 6211 if (offset % component_size > 0) { 6212 SetGLError(GL_INVALID_OPERATION, 6213 "glVertexAttribPointer", "offset not valid for type"); 6214 return error::kNoError; 6215 } 6216 if (stride % component_size > 0) { 6217 SetGLError(GL_INVALID_OPERATION, 6218 "glVertexAttribPointer", "stride not valid for type"); 6219 return error::kNoError; 6220 } 6221 state_.vertex_attrib_manager->SetAttribInfo( 6222 indx, 6223 state_.bound_array_buffer, 6224 size, 6225 type, 6226 normalized, 6227 stride, 6228 stride != 0 ? stride : component_size * size, 6229 offset); 6230 if (type != GL_FIXED) { 6231 glVertexAttribPointer(indx, size, type, normalized, stride, ptr); 6232 } 6233 return error::kNoError; 6234} 6235 6236void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width, 6237 GLsizei height) { 6238 state_.viewport_x = x; 6239 state_.viewport_y = y; 6240 state_.viewport_width = std::min(width, viewport_max_width_); 6241 state_.viewport_height = std::min(height, viewport_max_height_); 6242 glViewport(x, y, width, height); 6243} 6244 6245error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE( 6246 uint32 immediate_data_size, const gles2::VertexAttribDivisorANGLE& c) { 6247 if (!features().angle_instanced_arrays) { 6248 SetGLError(GL_INVALID_OPERATION, 6249 "glVertexAttribDivisorANGLE", "function not available"); 6250 } 6251 GLuint index = c.index; 6252 GLuint divisor = c.divisor; 6253 if (index >= group_->max_vertex_attribs()) { 6254 SetGLError(GL_INVALID_VALUE, 6255 "glVertexAttribDivisorANGLE", "index out of range"); 6256 return error::kNoError; 6257 } 6258 6259 state_.vertex_attrib_manager->SetDivisor( 6260 index, 6261 divisor); 6262 glVertexAttribDivisorANGLE(index, divisor); 6263 return error::kNoError; 6264} 6265 6266error::Error GLES2DecoderImpl::HandleReadPixels( 6267 uint32 immediate_data_size, const gles2::ReadPixels& c) { 6268 GLint x = c.x; 6269 GLint y = c.y; 6270 GLsizei width = c.width; 6271 GLsizei height = c.height; 6272 GLenum format = c.format; 6273 GLenum type = c.type; 6274 if (width < 0 || height < 0) { 6275 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0"); 6276 return error::kNoError; 6277 } 6278 typedef gles2::ReadPixels::Result Result; 6279 uint32 pixels_size; 6280 if (!GLES2Util::ComputeImageDataSizes( 6281 width, height, format, type, state_.pack_alignment, &pixels_size, 6282 NULL, NULL)) { 6283 return error::kOutOfBounds; 6284 } 6285 void* pixels = GetSharedMemoryAs<void*>( 6286 c.pixels_shm_id, c.pixels_shm_offset, pixels_size); 6287 Result* result = GetSharedMemoryAs<Result*>( 6288 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 6289 if (!pixels || !result) { 6290 return error::kOutOfBounds; 6291 } 6292 6293 if (!validators_->read_pixel_format.IsValid(format)) { 6294 SetGLErrorInvalidEnum("glReadPixels", format, "format"); 6295 return error::kNoError; 6296 } 6297 if (!validators_->pixel_type.IsValid(type)) { 6298 SetGLErrorInvalidEnum("glReadPixels", type, "type"); 6299 return error::kNoError; 6300 } 6301 if (width == 0 || height == 0) { 6302 return error::kNoError; 6303 } 6304 6305 // Get the size of the current fbo or backbuffer. 6306 gfx::Size max_size = GetBoundReadFrameBufferSize(); 6307 6308 int32 max_x; 6309 int32 max_y; 6310 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) { 6311 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); 6312 return error::kNoError; 6313 } 6314 6315 if (!CheckBoundFramebuffersValid("glReadPixels")) { 6316 return error::kNoError; 6317 } 6318 6319 CopyRealGLErrorsToWrapper(); 6320 6321 ScopedResolvedFrameBufferBinder binder(this, false, true); 6322 6323 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) { 6324 // The user requested an out of range area. Get the results 1 line 6325 // at a time. 6326 uint32 temp_size; 6327 uint32 unpadded_row_size; 6328 uint32 padded_row_size; 6329 if (!GLES2Util::ComputeImageDataSizes( 6330 width, 2, format, type, state_.pack_alignment, &temp_size, 6331 &unpadded_row_size, &padded_row_size)) { 6332 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); 6333 return error::kNoError; 6334 } 6335 6336 GLint dest_x_offset = std::max(-x, 0); 6337 uint32 dest_row_offset; 6338 if (!GLES2Util::ComputeImageDataSizes( 6339 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset, 6340 NULL, NULL)) { 6341 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); 6342 return error::kNoError; 6343 } 6344 6345 // Copy each row into the larger dest rect. 6346 int8* dst = static_cast<int8*>(pixels); 6347 GLint read_x = std::max(0, x); 6348 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x)); 6349 GLint read_width = read_end_x - read_x; 6350 for (GLint yy = 0; yy < height; ++yy) { 6351 GLint ry = y + yy; 6352 6353 // Clear the row. 6354 memset(dst, 0, unpadded_row_size); 6355 6356 // If the row is in range, copy it. 6357 if (ry >= 0 && ry < max_size.height() && read_width > 0) { 6358 glReadPixels( 6359 read_x, ry, read_width, 1, format, type, dst + dest_row_offset); 6360 } 6361 dst += padded_row_size; 6362 } 6363 } else { 6364 glReadPixels(x, y, width, height, format, type, pixels); 6365 } 6366 GLenum error = PeekGLError(); 6367 if (error == GL_NO_ERROR) { 6368 *result = true; 6369 6370 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); 6371 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); 6372 if ((channels_exist & 0x0008) == 0 && 6373 workarounds().clear_alpha_in_readpixels) { 6374 // Set the alpha to 255 because some drivers are buggy in this regard. 6375 uint32 temp_size; 6376 6377 uint32 unpadded_row_size; 6378 uint32 padded_row_size; 6379 if (!GLES2Util::ComputeImageDataSizes( 6380 width, 2, format, type, state_.pack_alignment, &temp_size, 6381 &unpadded_row_size, &padded_row_size)) { 6382 SetGLError(GL_INVALID_VALUE, "glReadPixels", "dimensions out of range"); 6383 return error::kNoError; 6384 } 6385 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time 6386 // of this implementation. 6387 if (type != GL_UNSIGNED_BYTE) { 6388 SetGLError( 6389 GL_INVALID_OPERATION, "glReadPixels", 6390 "unsupported readPixel format"); 6391 return error::kNoError; 6392 } 6393 switch (format) { 6394 case GL_RGBA: 6395 case GL_BGRA_EXT: 6396 case GL_ALPHA: { 6397 int offset = (format == GL_ALPHA) ? 0 : 3; 6398 int step = (format == GL_ALPHA) ? 1 : 4; 6399 uint8* dst = static_cast<uint8*>(pixels) + offset; 6400 for (GLint yy = 0; yy < height; ++yy) { 6401 uint8* end = dst + unpadded_row_size; 6402 for (uint8* d = dst; d < end; d += step) { 6403 *d = 255; 6404 } 6405 dst += padded_row_size; 6406 } 6407 break; 6408 } 6409 default: 6410 break; 6411 } 6412 } 6413 } 6414 6415 return error::kNoError; 6416} 6417 6418error::Error GLES2DecoderImpl::HandlePixelStorei( 6419 uint32 immediate_data_size, const gles2::PixelStorei& c) { 6420 GLenum pname = c.pname; 6421 GLenum param = c.param; 6422 if (!validators_->pixel_store.IsValid(pname)) { 6423 SetGLErrorInvalidEnum("glPixelStorei", pname, "pname"); 6424 return error::kNoError; 6425 } 6426 switch (pname) { 6427 case GL_PACK_ALIGNMENT: 6428 case GL_UNPACK_ALIGNMENT: 6429 if (!validators_->pixel_store_alignment.IsValid(param)) { 6430 SetGLError(GL_INVALID_VALUE, 6431 "glPixelStore", "param GL_INVALID_VALUE"); 6432 return error::kNoError; 6433 } 6434 break; 6435 case GL_UNPACK_FLIP_Y_CHROMIUM: 6436 unpack_flip_y_ = (param != 0); 6437 return error::kNoError; 6438 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM: 6439 unpack_premultiply_alpha_ = (param != 0); 6440 return error::kNoError; 6441 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM: 6442 unpack_unpremultiply_alpha_ = (param != 0); 6443 return error::kNoError; 6444 default: 6445 break; 6446 } 6447 glPixelStorei(pname, param); 6448 switch (pname) { 6449 case GL_PACK_ALIGNMENT: 6450 state_.pack_alignment = param; 6451 break; 6452 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: 6453 state_.pack_reverse_row_order = (param != 0); 6454 break; 6455 case GL_UNPACK_ALIGNMENT: 6456 state_.unpack_alignment = param; 6457 break; 6458 default: 6459 // Validation should have prevented us from getting here. 6460 NOTREACHED(); 6461 break; 6462 } 6463 return error::kNoError; 6464} 6465 6466error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM( 6467 uint32 immediate_data_size, const gles2::PostSubBufferCHROMIUM& c) { 6468 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM"); 6469 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) { 6470 SetGLError(GL_INVALID_OPERATION, 6471 "glPostSubBufferCHROMIUM", "command not supported by surface"); 6472 return error::kNoError; 6473 } 6474 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) { 6475 return error::kNoError; 6476 } else { 6477 LOG(ERROR) << "Context lost because PostSubBuffer failed."; 6478 return error::kLostContext; 6479 } 6480} 6481 6482error::Error GLES2DecoderImpl::GetAttribLocationHelper( 6483 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 6484 const std::string& name_str) { 6485 if (!StringIsValidForGLES(name_str.c_str())) { 6486 SetGLError(GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character"); 6487 return error::kNoError; 6488 } 6489 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( 6490 client_id, "glGetAttribLocation"); 6491 if (!info) { 6492 return error::kNoError; 6493 } 6494 if (!info->IsValid()) { 6495 SetGLError( 6496 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked"); 6497 return error::kNoError; 6498 } 6499 GLint* location = GetSharedMemoryAs<GLint*>( 6500 location_shm_id, location_shm_offset, sizeof(GLint)); 6501 if (!location) { 6502 return error::kOutOfBounds; 6503 } 6504 // Require the client to init this incase the context is lost and we are no 6505 // longer executing commands. 6506 if (*location != -1) { 6507 return error::kGenericError; 6508 } 6509 *location = info->GetAttribLocation(name_str); 6510 return error::kNoError; 6511} 6512 6513error::Error GLES2DecoderImpl::HandleGetAttribLocation( 6514 uint32 immediate_data_size, const gles2::GetAttribLocation& c) { 6515 uint32 name_size = c.data_size; 6516 const char* name = GetSharedMemoryAs<const char*>( 6517 c.name_shm_id, c.name_shm_offset, name_size); 6518 if (!name) { 6519 return error::kOutOfBounds; 6520 } 6521 String name_str(name, name_size); 6522 return GetAttribLocationHelper( 6523 c.program, c.location_shm_id, c.location_shm_offset, name_str); 6524} 6525 6526error::Error GLES2DecoderImpl::HandleGetAttribLocationImmediate( 6527 uint32 immediate_data_size, const gles2::GetAttribLocationImmediate& c) { 6528 uint32 name_size = c.data_size; 6529 const char* name = GetImmediateDataAs<const char*>( 6530 c, name_size, immediate_data_size); 6531 if (!name) { 6532 return error::kOutOfBounds; 6533 } 6534 String name_str(name, name_size); 6535 return GetAttribLocationHelper( 6536 c.program, c.location_shm_id, c.location_shm_offset, name_str); 6537} 6538 6539error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket( 6540 uint32 immediate_data_size, const gles2::GetAttribLocationBucket& c) { 6541 Bucket* bucket = GetBucket(c.name_bucket_id); 6542 if (!bucket) { 6543 return error::kInvalidArguments; 6544 } 6545 std::string name_str; 6546 if (!bucket->GetAsString(&name_str)) { 6547 return error::kInvalidArguments; 6548 } 6549 return GetAttribLocationHelper( 6550 c.program, c.location_shm_id, c.location_shm_offset, name_str); 6551} 6552 6553error::Error GLES2DecoderImpl::GetUniformLocationHelper( 6554 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset, 6555 const std::string& name_str) { 6556 if (!StringIsValidForGLES(name_str.c_str())) { 6557 SetGLError(GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character"); 6558 return error::kNoError; 6559 } 6560 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( 6561 client_id, "glUniformLocation"); 6562 if (!info) { 6563 return error::kNoError; 6564 } 6565 if (!info->IsValid()) { 6566 SetGLError( 6567 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked"); 6568 return error::kNoError; 6569 } 6570 GLint* location = GetSharedMemoryAs<GLint*>( 6571 location_shm_id, location_shm_offset, sizeof(GLint)); 6572 if (!location) { 6573 return error::kOutOfBounds; 6574 } 6575 // Require the client to init this incase the context is lost an we are no 6576 // longer executing commands. 6577 if (*location != -1) { 6578 return error::kGenericError; 6579 } 6580 *location = info->GetUniformFakeLocation(name_str); 6581 return error::kNoError; 6582} 6583 6584error::Error GLES2DecoderImpl::HandleGetUniformLocation( 6585 uint32 immediate_data_size, const gles2::GetUniformLocation& c) { 6586 uint32 name_size = c.data_size; 6587 const char* name = GetSharedMemoryAs<const char*>( 6588 c.name_shm_id, c.name_shm_offset, name_size); 6589 if (!name) { 6590 return error::kOutOfBounds; 6591 } 6592 String name_str(name, name_size); 6593 return GetUniformLocationHelper( 6594 c.program, c.location_shm_id, c.location_shm_offset, name_str); 6595} 6596 6597error::Error GLES2DecoderImpl::HandleGetUniformLocationImmediate( 6598 uint32 immediate_data_size, const gles2::GetUniformLocationImmediate& c) { 6599 uint32 name_size = c.data_size; 6600 const char* name = GetImmediateDataAs<const char*>( 6601 c, name_size, immediate_data_size); 6602 if (!name) { 6603 return error::kOutOfBounds; 6604 } 6605 String name_str(name, name_size); 6606 return GetUniformLocationHelper( 6607 c.program, c.location_shm_id, c.location_shm_offset, name_str); 6608} 6609 6610error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket( 6611 uint32 immediate_data_size, const gles2::GetUniformLocationBucket& c) { 6612 Bucket* bucket = GetBucket(c.name_bucket_id); 6613 if (!bucket) { 6614 return error::kInvalidArguments; 6615 } 6616 std::string name_str; 6617 if (!bucket->GetAsString(&name_str)) { 6618 return error::kInvalidArguments; 6619 } 6620 return GetUniformLocationHelper( 6621 c.program, c.location_shm_id, c.location_shm_offset, name_str); 6622} 6623 6624error::Error GLES2DecoderImpl::HandleGetString( 6625 uint32 immediate_data_size, const gles2::GetString& c) { 6626 GLenum name = static_cast<GLenum>(c.name); 6627 if (!validators_->string_type.IsValid(name)) { 6628 SetGLErrorInvalidEnum("glGetString", name, "name"); 6629 return error::kNoError; 6630 } 6631 const char* gl_str = reinterpret_cast<const char*>(glGetString(name)); 6632 const char* str = NULL; 6633 std::string extensions; 6634 switch (name) { 6635 case GL_VERSION: 6636 str = "OpenGL ES 2.0 Chromium"; 6637 break; 6638 case GL_SHADING_LANGUAGE_VERSION: 6639 str = "OpenGL ES GLSL ES 1.0 Chromium"; 6640 break; 6641 case GL_RENDERER: 6642 str = "Chromium"; 6643 break; 6644 case GL_VENDOR: 6645 str = "Chromium"; 6646 break; 6647 case GL_EXTENSIONS: 6648 { 6649 // For WebGL contexts, strip out the OES derivatives extension if it has 6650 // not been enabled. 6651 if (force_webgl_glsl_validation_ && 6652 !derivatives_explicitly_enabled_) { 6653 extensions = feature_info_->extensions(); 6654 size_t offset = extensions.find(kOESDerivativeExtension); 6655 if (std::string::npos != offset) { 6656 extensions.replace(offset, 6657 offset + arraysize(kOESDerivativeExtension), 6658 std::string()); 6659 } 6660 } else { 6661 extensions = feature_info_->extensions().c_str(); 6662 } 6663 std::string surface_extensions = surface_->GetExtensions(); 6664 if (!surface_extensions.empty()) 6665 extensions += " " + surface_extensions; 6666 str = extensions.c_str(); 6667 } 6668 break; 6669 default: 6670 str = gl_str; 6671 break; 6672 } 6673 Bucket* bucket = CreateBucket(c.bucket_id); 6674 bucket->SetFromString(str); 6675 return error::kNoError; 6676} 6677 6678void GLES2DecoderImpl::DoBufferData( 6679 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) { 6680 if (!validators_->buffer_target.IsValid(target)) { 6681 SetGLErrorInvalidEnum("glBufferData", target, "target"); 6682 return; 6683 } 6684 if (!validators_->buffer_usage.IsValid(usage)) { 6685 SetGLErrorInvalidEnum("glBufferData", usage, "usage"); 6686 return; 6687 } 6688 if (size < 0) { 6689 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0"); 6690 return; 6691 } 6692 BufferManager::BufferInfo* info = GetBufferInfoForTarget(target); 6693 if (!info) { 6694 SetGLError(GL_INVALID_VALUE, "glBufferData", "unknown buffer"); 6695 return; 6696 } 6697 // Clear the buffer to 0 if no initial data was passed in. 6698 scoped_array<int8> zero; 6699 if (!data) { 6700 zero.reset(new int8[size]); 6701 memset(zero.get(), 0, size); 6702 data = zero.get(); 6703 } 6704 6705 CopyRealGLErrorsToWrapper(); 6706 glBufferData(target, size, data, usage); 6707 GLenum error = PeekGLError(); 6708 if (error == GL_NO_ERROR) { 6709 buffer_manager()->SetInfo(info, size, usage); 6710 info->SetRange(0, size, data); 6711 } else { 6712 buffer_manager()->SetInfo(info, 0, usage); 6713 } 6714} 6715 6716error::Error GLES2DecoderImpl::HandleBufferData( 6717 uint32 immediate_data_size, const gles2::BufferData& c) { 6718 GLenum target = static_cast<GLenum>(c.target); 6719 GLsizeiptr size = static_cast<GLsizeiptr>(c.size); 6720 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); 6721 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); 6722 GLenum usage = static_cast<GLenum>(c.usage); 6723 const void* data = NULL; 6724 if (data_shm_id != 0 || data_shm_offset != 0) { 6725 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size); 6726 if (!data) { 6727 return error::kOutOfBounds; 6728 } 6729 } 6730 DoBufferData(target, size, data, usage); 6731 return error::kNoError; 6732} 6733 6734error::Error GLES2DecoderImpl::HandleBufferDataImmediate( 6735 uint32 immediate_data_size, const gles2::BufferDataImmediate& c) { 6736 GLenum target = static_cast<GLenum>(c.target); 6737 GLsizeiptr size = static_cast<GLsizeiptr>(c.size); 6738 const void* data = GetImmediateDataAs<const void*>( 6739 c, size, immediate_data_size); 6740 if (!data) { 6741 return error::kOutOfBounds; 6742 } 6743 GLenum usage = static_cast<GLenum>(c.usage); 6744 DoBufferData(target, size, data, usage); 6745 return error::kNoError; 6746} 6747 6748void GLES2DecoderImpl::DoBufferSubData( 6749 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) { 6750 BufferManager::BufferInfo* info = GetBufferInfoForTarget(target); 6751 if (!info) { 6752 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer"); 6753 return; 6754 } 6755 if (!info->SetRange(offset, size, data)) { 6756 SetGLError(GL_INVALID_VALUE, "glBufferSubData", "out of range"); 6757 return; 6758 } 6759 glBufferSubData(target, offset, size, data); 6760} 6761 6762bool GLES2DecoderImpl::ClearLevel( 6763 unsigned service_id, 6764 unsigned bind_target, 6765 unsigned target, 6766 int level, 6767 unsigned format, 6768 unsigned type, 6769 int width, 6770 int height, 6771 bool is_texture_immutable) { 6772 uint32 channels = GLES2Util::GetChannelsForFormat(format); 6773 if (IsAngle() && (channels & GLES2Util::kDepth) != 0) { 6774 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D 6775 // on depth formats. 6776 GLuint fb = 0; 6777 glGenFramebuffersEXT(1, &fb); 6778 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb); 6779 6780 bool have_stencil = (channels & GLES2Util::kStencil) != 0; 6781 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : 6782 GL_DEPTH_ATTACHMENT; 6783 6784 glFramebufferTexture2DEXT( 6785 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level); 6786 // ANGLE promises a depth only attachment ok. 6787 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) != 6788 GL_FRAMEBUFFER_COMPLETE) { 6789 return false; 6790 } 6791 glClearStencil(0); 6792 glStencilMask(-1); 6793 glClearDepth(1.0f); 6794 glDepthMask(true); 6795 glDisable(GL_SCISSOR_TEST); 6796 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0)); 6797 6798 RestoreClearState(); 6799 6800 glDeleteFramebuffersEXT(1, &fb); 6801 FramebufferManager::FramebufferInfo* framebuffer = 6802 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT); 6803 GLuint fb_service_id = 6804 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId(); 6805 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id); 6806 return true; 6807 } 6808 6809 static const uint32 kMaxZeroSize = 1024 * 1024 * 4; 6810 6811 uint32 size; 6812 uint32 padded_row_size; 6813 if (!GLES2Util::ComputeImageDataSizes( 6814 width, height, format, type, state_.unpack_alignment, &size, 6815 NULL, &padded_row_size)) { 6816 return false; 6817 } 6818 6819 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size); 6820 6821 int tile_height; 6822 6823 if (size > kMaxZeroSize) { 6824 if (kMaxZeroSize < padded_row_size) { 6825 // That'd be an awfully large texture. 6826 return false; 6827 } 6828 // We should never have a large total size with a zero row size. 6829 DCHECK_GT(padded_row_size, 0U); 6830 tile_height = kMaxZeroSize / padded_row_size; 6831 if (!GLES2Util::ComputeImageDataSizes( 6832 width, tile_height, format, type, state_.unpack_alignment, &size, 6833 NULL, NULL)) { 6834 return false; 6835 } 6836 } else { 6837 tile_height = height; 6838 } 6839 6840 // Assumes the size has already been checked. 6841 scoped_array<char> zero(new char[size]); 6842 memset(zero.get(), 0, size); 6843 glBindTexture(bind_target, service_id); 6844 6845 GLint y = 0; 6846 while (y < height) { 6847 GLint h = y + tile_height > height ? height - y : tile_height; 6848 if (is_texture_immutable || h != height) { 6849 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get()); 6850 } else { 6851 WrappedTexImage2D( 6852 target, level, format, width, h, 0, format, type, zero.get()); 6853 } 6854 y += tile_height; 6855 } 6856 TextureManager::TextureInfo* info = GetTextureInfoForTarget(bind_target); 6857 glBindTexture(bind_target, info ? info->service_id() : 0); 6858 return true; 6859} 6860 6861namespace { 6862 6863const int kS3TCBlockWidth = 4; 6864const int kS3TCBlockHeight = 4; 6865const int kS3TCDXT1BlockSize = 8; 6866const int kS3TCDXT3AndDXT5BlockSize = 16; 6867const int kETC1BlockWidth = 4; 6868const int kETC1BlockHeight = 4; 6869const int kETC1BlockSize = 8; 6870 6871bool IsValidDXTSize(GLint level, GLsizei size) { 6872 return (size == 1) || 6873 (size == 2) || !(size % kS3TCBlockWidth); 6874} 6875 6876} // anonymous namespace. 6877 6878bool GLES2DecoderImpl::ValidateCompressedTexFuncData( 6879 const char* function_name, 6880 GLsizei width, GLsizei height, GLenum format, size_t size) { 6881 unsigned int bytes_required = 0; 6882 6883 switch (format) { 6884 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 6885 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: { 6886 int num_blocks_across = 6887 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; 6888 int num_blocks_down = 6889 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; 6890 int num_blocks = num_blocks_across * num_blocks_down; 6891 bytes_required = num_blocks * kS3TCDXT1BlockSize; 6892 break; 6893 } 6894 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 6895 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { 6896 int num_blocks_across = 6897 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth; 6898 int num_blocks_down = 6899 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight; 6900 int num_blocks = num_blocks_across * num_blocks_down; 6901 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize; 6902 break; 6903 } 6904 case GL_ETC1_RGB8_OES: { 6905 int num_blocks_across = 6906 (width + kETC1BlockWidth - 1) / kETC1BlockWidth; 6907 int num_blocks_down = 6908 (height + kETC1BlockHeight - 1) / kETC1BlockHeight; 6909 int num_blocks = num_blocks_across * num_blocks_down; 6910 bytes_required = num_blocks * kETC1BlockSize; 6911 break; 6912 } 6913 default: 6914 SetGLErrorInvalidEnum(function_name, format, "format"); 6915 return false; 6916 } 6917 6918 if (size != bytes_required) { 6919 SetGLError( 6920 GL_INVALID_VALUE, function_name, "size is not correct for dimensions"); 6921 return false; 6922 } 6923 6924 return true; 6925} 6926 6927bool GLES2DecoderImpl::ValidateCompressedTexDimensions( 6928 const char* function_name, 6929 GLint level, GLsizei width, GLsizei height, GLenum format) { 6930 switch (format) { 6931 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 6932 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 6933 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 6934 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { 6935 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) { 6936 SetGLError( 6937 GL_INVALID_OPERATION, function_name, 6938 "width or height invalid for level"); 6939 return false; 6940 } 6941 return true; 6942 } 6943 case GL_ETC1_RGB8_OES: 6944 if (width <= 0 || height <= 0) { 6945 SetGLError( 6946 GL_INVALID_OPERATION, function_name, 6947 "width or height invalid for level"); 6948 return false; 6949 } 6950 return true; 6951 default: 6952 return false; 6953 } 6954} 6955 6956bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions( 6957 const char* function_name, 6958 GLenum target, GLint level, GLint xoffset, GLint yoffset, 6959 GLsizei width, GLsizei height, GLenum format, 6960 TextureManager::TextureInfo* texture) { 6961 if (xoffset < 0 || yoffset < 0) { 6962 SetGLError( 6963 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0"); 6964 return false; 6965 } 6966 6967 switch (format) { 6968 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 6969 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 6970 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: 6971 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: { 6972 const int kBlockWidth = 4; 6973 const int kBlockHeight = 4; 6974 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) { 6975 SetGLError( 6976 GL_INVALID_OPERATION, function_name, 6977 "xoffset or yoffset not multiple of 4"); 6978 return false; 6979 } 6980 GLsizei tex_width = 0; 6981 GLsizei tex_height = 0; 6982 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) || 6983 width - xoffset > tex_width || 6984 height - yoffset > tex_height) { 6985 SetGLError( 6986 GL_INVALID_OPERATION, function_name, "dimensions out of range"); 6987 return false; 6988 } 6989 return ValidateCompressedTexDimensions( 6990 function_name, level, width, height, format); 6991 } 6992 case GL_ETC1_RGB8_OES: { 6993 SetGLError( 6994 GL_INVALID_OPERATION, function_name, 6995 "TexsubImage2d not supported for ECT1_RGB8_OES textures"); 6996 return false; 6997 } 6998 default: 6999 return false; 7000 } 7001} 7002 7003error::Error GLES2DecoderImpl::DoCompressedTexImage2D( 7004 GLenum target, 7005 GLint level, 7006 GLenum internal_format, 7007 GLsizei width, 7008 GLsizei height, 7009 GLint border, 7010 GLsizei image_size, 7011 const void* data) { 7012 // TODO(gman): Validate image_size is correct for width, height and format. 7013 if (!validators_->texture_target.IsValid(target)) { 7014 SetGLErrorInvalidEnum("glCompressedTexImage2D", target, "target"); 7015 return error::kNoError; 7016 } 7017 if (!validators_->compressed_texture_format.IsValid( 7018 internal_format)) { 7019 SetGLErrorInvalidEnum( 7020 "glCompressedTexImage2D", internal_format, "internal_format"); 7021 return error::kNoError; 7022 } 7023 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || 7024 border != 0) { 7025 SetGLError(GL_INVALID_VALUE, 7026 "glCompressedTexImage2D", "dimensions out of range"); 7027 return error::kNoError; 7028 } 7029 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 7030 if (!info) { 7031 SetGLError(GL_INVALID_VALUE, 7032 "glCompressedTexImage2D", "unknown texture target"); 7033 return error::kNoError; 7034 } 7035 if (info->IsImmutable()) { 7036 SetGLError(GL_INVALID_OPERATION, 7037 "glCompressedTexImage2D", "texture is immutable"); 7038 return error::kNoError; 7039 } 7040 7041 if (!ValidateCompressedTexDimensions( 7042 "glCompressedTexImage2D", level, width, height, internal_format) || 7043 !ValidateCompressedTexFuncData( 7044 "glCompressedTexImage2D", width, height, internal_format, image_size)) { 7045 return error::kNoError; 7046 } 7047 7048 if (info->IsAttachedToFramebuffer()) { 7049 clear_state_dirty_ = true; 7050 // TODO(gman): If textures tracked which framebuffers they were attached to 7051 // we could just mark those framebuffers as not complete. 7052 framebuffer_manager()->IncFramebufferStateChangeCount(); 7053 } 7054 7055 scoped_array<int8> zero; 7056 if (!data) { 7057 zero.reset(new int8[image_size]); 7058 memset(zero.get(), 0, image_size); 7059 data = zero.get(); 7060 } 7061 CopyRealGLErrorsToWrapper(); 7062 glCompressedTexImage2D( 7063 target, level, internal_format, width, height, border, image_size, data); 7064 GLenum error = PeekGLError(); 7065 if (error == GL_NO_ERROR) { 7066 texture_manager()->SetLevelInfo( 7067 info, target, level, internal_format, width, height, 1, border, 0, 0, 7068 true); 7069 } 7070 return error::kNoError; 7071} 7072 7073error::Error GLES2DecoderImpl::HandleCompressedTexImage2D( 7074 uint32 immediate_data_size, const gles2::CompressedTexImage2D& c) { 7075 GLenum target = static_cast<GLenum>(c.target); 7076 GLint level = static_cast<GLint>(c.level); 7077 GLenum internal_format = static_cast<GLenum>(c.internalformat); 7078 GLsizei width = static_cast<GLsizei>(c.width); 7079 GLsizei height = static_cast<GLsizei>(c.height); 7080 GLint border = static_cast<GLint>(c.border); 7081 GLsizei image_size = static_cast<GLsizei>(c.imageSize); 7082 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); 7083 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); 7084 const void* data = NULL; 7085 if (data_shm_id != 0 || data_shm_offset != 0) { 7086 data = GetSharedMemoryAs<const void*>( 7087 data_shm_id, data_shm_offset, image_size); 7088 if (!data) { 7089 return error::kOutOfBounds; 7090 } 7091 } 7092 return DoCompressedTexImage2D( 7093 target, level, internal_format, width, height, border, image_size, data); 7094} 7095 7096error::Error GLES2DecoderImpl::HandleCompressedTexImage2DImmediate( 7097 uint32 immediate_data_size, const gles2::CompressedTexImage2DImmediate& c) { 7098 GLenum target = static_cast<GLenum>(c.target); 7099 GLint level = static_cast<GLint>(c.level); 7100 GLenum internal_format = static_cast<GLenum>(c.internalformat); 7101 GLsizei width = static_cast<GLsizei>(c.width); 7102 GLsizei height = static_cast<GLsizei>(c.height); 7103 GLint border = static_cast<GLint>(c.border); 7104 GLsizei image_size = static_cast<GLsizei>(c.imageSize); 7105 const void* data = GetImmediateDataAs<const void*>( 7106 c, image_size, immediate_data_size); 7107 if (!data) { 7108 return error::kOutOfBounds; 7109 } 7110 return DoCompressedTexImage2D( 7111 target, level, internal_format, width, height, border, image_size, data); 7112} 7113 7114error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket( 7115 uint32 immediate_data_size, const gles2::CompressedTexImage2DBucket& c) { 7116 GLenum target = static_cast<GLenum>(c.target); 7117 GLint level = static_cast<GLint>(c.level); 7118 GLenum internal_format = static_cast<GLenum>(c.internalformat); 7119 GLsizei width = static_cast<GLsizei>(c.width); 7120 GLsizei height = static_cast<GLsizei>(c.height); 7121 GLint border = static_cast<GLint>(c.border); 7122 Bucket* bucket = GetBucket(c.bucket_id); 7123 if (!bucket) { 7124 return error::kInvalidArguments; 7125 } 7126 uint32 data_size = bucket->size(); 7127 GLsizei imageSize = data_size; 7128 const void* data = bucket->GetData(0, data_size); 7129 if (!data) { 7130 return error::kInvalidArguments; 7131 } 7132 return DoCompressedTexImage2D( 7133 target, level, internal_format, width, height, border, 7134 imageSize, data); 7135} 7136 7137error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket( 7138 uint32 immediate_data_size, 7139 const gles2::CompressedTexSubImage2DBucket& c) { 7140 GLenum target = static_cast<GLenum>(c.target); 7141 GLint level = static_cast<GLint>(c.level); 7142 GLint xoffset = static_cast<GLint>(c.xoffset); 7143 GLint yoffset = static_cast<GLint>(c.yoffset); 7144 GLsizei width = static_cast<GLsizei>(c.width); 7145 GLsizei height = static_cast<GLsizei>(c.height); 7146 GLenum format = static_cast<GLenum>(c.format); 7147 Bucket* bucket = GetBucket(c.bucket_id); 7148 if (!bucket) { 7149 return error::kInvalidArguments; 7150 } 7151 uint32 data_size = bucket->size(); 7152 GLsizei imageSize = data_size; 7153 const void* data = bucket->GetData(0, data_size); 7154 if (!data) { 7155 return error::kInvalidArguments; 7156 } 7157 if (!validators_->texture_target.IsValid(target)) { 7158 SetGLError( 7159 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target"); 7160 return error::kNoError; 7161 } 7162 if (!validators_->compressed_texture_format.IsValid(format)) { 7163 SetGLErrorInvalidEnum("glCompressedTexSubImage2D", format, "format"); 7164 return error::kNoError; 7165 } 7166 if (width < 0) { 7167 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0"); 7168 return error::kNoError; 7169 } 7170 if (height < 0) { 7171 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0"); 7172 return error::kNoError; 7173 } 7174 if (imageSize < 0) { 7175 SetGLError(GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0"); 7176 return error::kNoError; 7177 } 7178 DoCompressedTexSubImage2D( 7179 target, level, xoffset, yoffset, width, height, format, imageSize, data); 7180 return error::kNoError; 7181} 7182 7183bool GLES2DecoderImpl::ValidateTextureParameters( 7184 const char* function_name, 7185 GLenum target, GLenum format, GLenum type, GLint level) { 7186 if (!feature_info_->GetTextureFormatValidator(format).IsValid(type)) { 7187 SetGLError(GL_INVALID_OPERATION, function_name, 7188 (std::string("invalid type ") + 7189 GLES2Util::GetStringEnum(type) + " for format " + 7190 GLES2Util::GetStringEnum(format)).c_str()); 7191 return false; 7192 } 7193 7194 uint32 channels = GLES2Util::GetChannelsForFormat(format); 7195 if ((channels & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && level) { 7196 SetGLError(GL_INVALID_OPERATION, function_name, 7197 (std::string("invalid type ") + 7198 GLES2Util::GetStringEnum(type) + " for format " + 7199 GLES2Util::GetStringEnum(format)).c_str()); 7200 return false; 7201 } 7202 return true; 7203} 7204 7205error::Error GLES2DecoderImpl::DoTexImage2D( 7206 GLenum target, 7207 GLint level, 7208 GLenum internal_format, 7209 GLsizei width, 7210 GLsizei height, 7211 GLint border, 7212 GLenum format, 7213 GLenum type, 7214 const void* pixels, 7215 uint32 pixels_size) { 7216 if (!validators_->texture_target.IsValid(target)) { 7217 SetGLErrorInvalidEnum("glTexImage2D", target, "target"); 7218 return error::kNoError; 7219 } 7220 if (!validators_->texture_format.IsValid(internal_format)) { 7221 SetGLErrorInvalidEnum("glTexImage2D", internal_format, "internal_format"); 7222 return error::kNoError; 7223 } 7224 if (!validators_->texture_format.IsValid(format)) { 7225 SetGLErrorInvalidEnum("glTexImage2D", format, "format"); 7226 return error::kNoError; 7227 } 7228 if (!validators_->pixel_type.IsValid(type)) { 7229 SetGLErrorInvalidEnum("glTexImage2D", type, "type"); 7230 return error::kNoError; 7231 } 7232 if (format != internal_format) { 7233 SetGLError(GL_INVALID_OPERATION, 7234 "glTexImage2D", "format != internalFormat"); 7235 return error::kNoError; 7236 } 7237 if (!ValidateTextureParameters("glTexImage2D", target, format, type, level)) { 7238 return error::kNoError; 7239 } 7240 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || 7241 border != 0) { 7242 SetGLError(GL_INVALID_VALUE, "glTexImage2D", "dimensions out of range"); 7243 return error::kNoError; 7244 } 7245 if ((GLES2Util::GetChannelsForFormat(format) & 7246 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && pixels) { 7247 SetGLError( 7248 GL_INVALID_OPERATION, 7249 "glTexImage2D", "can not supply data for depth or stencil textures"); 7250 return error::kNoError; 7251 } 7252 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 7253 if (!info) { 7254 SetGLError(GL_INVALID_OPERATION, 7255 "glTexImage2D", "unknown texture for target"); 7256 return error::kNoError; 7257 } 7258 7259 if (info->IsImmutable()) { 7260 SetGLError(GL_INVALID_OPERATION, 7261 "glTexImage2D", "texture is immutable"); 7262 return error::kNoError; 7263 } 7264 7265 GLsizei tex_width = 0; 7266 GLsizei tex_height = 0; 7267 GLenum tex_type = 0; 7268 GLenum tex_format = 0; 7269 bool level_is_same = 7270 info->GetLevelSize(target, level, &tex_width, &tex_height) && 7271 info->GetLevelType(target, level, &tex_type, &tex_format) && 7272 width == tex_width && height == tex_height && 7273 type == tex_type && format == tex_format; 7274 7275 if (level_is_same && !pixels) { 7276 // Just set the level info but mark the texture as uncleared. 7277 texture_manager()->SetLevelInfo( 7278 info, 7279 target, level, internal_format, width, height, 1, border, format, type, 7280 false); 7281 tex_image_2d_failed_ = false; 7282 return error::kNoError; 7283 } 7284 7285 if (info->IsAttachedToFramebuffer()) { 7286 clear_state_dirty_ = true; 7287 // TODO(gman): If textures tracked which framebuffers they were attached to 7288 // we could just mark those framebuffers as not complete. 7289 framebuffer_manager()->IncFramebufferStateChangeCount(); 7290 } 7291 7292 if (!teximage2d_faster_than_texsubimage2d_ && level_is_same && pixels) { 7293 glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels); 7294 texture_manager()->SetLevelCleared(info, target, level); 7295 tex_image_2d_failed_ = false; 7296 return error::kNoError; 7297 } 7298 7299 CopyRealGLErrorsToWrapper(); 7300 WrappedTexImage2D( 7301 target, level, internal_format, width, height, border, format, type, 7302 pixels); 7303 GLenum error = PeekGLError(); 7304 if (error == GL_NO_ERROR) { 7305 texture_manager()->SetLevelInfo( 7306 info, 7307 target, level, internal_format, width, height, 1, border, format, type, 7308 pixels != NULL); 7309 tex_image_2d_failed_ = false; 7310 } 7311 return error::kNoError; 7312} 7313 7314error::Error GLES2DecoderImpl::HandleTexImage2D( 7315 uint32 immediate_data_size, const gles2::TexImage2D& c) { 7316 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D"); 7317 tex_image_2d_failed_ = true; 7318 GLenum target = static_cast<GLenum>(c.target); 7319 GLint level = static_cast<GLint>(c.level); 7320 GLint internal_format = static_cast<GLint>(c.internalformat); 7321 GLsizei width = static_cast<GLsizei>(c.width); 7322 GLsizei height = static_cast<GLsizei>(c.height); 7323 GLint border = static_cast<GLint>(c.border); 7324 GLenum format = static_cast<GLenum>(c.format); 7325 GLenum type = static_cast<GLenum>(c.type); 7326 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); 7327 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); 7328 uint32 pixels_size; 7329 if (!GLES2Util::ComputeImageDataSizes( 7330 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL, 7331 NULL)) { 7332 return error::kOutOfBounds; 7333 } 7334 const void* pixels = NULL; 7335 if (pixels_shm_id != 0 || pixels_shm_offset != 0) { 7336 pixels = GetSharedMemoryAs<const void*>( 7337 pixels_shm_id, pixels_shm_offset, pixels_size); 7338 if (!pixels) { 7339 return error::kOutOfBounds; 7340 } 7341 } 7342 return DoTexImage2D( 7343 target, level, internal_format, width, height, border, format, type, 7344 pixels, pixels_size); 7345} 7346 7347error::Error GLES2DecoderImpl::HandleTexImage2DImmediate( 7348 uint32 immediate_data_size, const gles2::TexImage2DImmediate& c) { 7349 GLenum target = static_cast<GLenum>(c.target); 7350 GLint level = static_cast<GLint>(c.level); 7351 GLint internal_format = static_cast<GLint>(c.internalformat); 7352 GLsizei width = static_cast<GLsizei>(c.width); 7353 GLsizei height = static_cast<GLsizei>(c.height); 7354 GLint border = static_cast<GLint>(c.border); 7355 GLenum format = static_cast<GLenum>(c.format); 7356 GLenum type = static_cast<GLenum>(c.type); 7357 uint32 size; 7358 if (!GLES2Util::ComputeImageDataSizes( 7359 width, height, format, type, state_.unpack_alignment, &size, 7360 NULL, NULL)) { 7361 return error::kOutOfBounds; 7362 } 7363 const void* pixels = GetImmediateDataAs<const void*>( 7364 c, size, immediate_data_size); 7365 if (!pixels) { 7366 return error::kOutOfBounds; 7367 } 7368 DoTexImage2D( 7369 target, level, internal_format, width, height, border, format, type, 7370 pixels, size); 7371 return error::kNoError; 7372} 7373 7374void GLES2DecoderImpl::DoCompressedTexSubImage2D( 7375 GLenum target, 7376 GLint level, 7377 GLint xoffset, 7378 GLint yoffset, 7379 GLsizei width, 7380 GLsizei height, 7381 GLenum format, 7382 GLsizei image_size, 7383 const void * data) { 7384 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 7385 if (!info) { 7386 SetGLError(GL_INVALID_OPERATION, 7387 "glCompressedTexSubImage2D", "unknown texture for target"); 7388 return; 7389 } 7390 GLenum type = 0; 7391 GLenum internal_format = 0; 7392 if (!info->GetLevelType(target, level, &type, &internal_format)) { 7393 SetGLError( 7394 GL_INVALID_OPERATION, 7395 "glCompressedTexSubImage2D", "level does not exist."); 7396 return; 7397 } 7398 if (internal_format != format) { 7399 SetGLError( 7400 GL_INVALID_OPERATION, 7401 "glCompressedTexSubImage2D", "format does not match internal format."); 7402 return; 7403 } 7404 if (!info->ValidForTexture( 7405 target, level, xoffset, yoffset, width, height, format, type)) { 7406 SetGLError(GL_INVALID_VALUE, 7407 "glCompressedTexSubImage2D", "bad dimensions."); 7408 return; 7409 } 7410 7411 if (!ValidateCompressedTexFuncData( 7412 "glCompressedTexSubImage2D", width, height, format, image_size) || 7413 !ValidateCompressedTexSubDimensions( 7414 "glCompressedTexSubImage2D", 7415 target, level, xoffset, yoffset, width, height, format, info)) { 7416 return; 7417 } 7418 7419 7420 // Note: There is no need to deal with texture cleared tracking here 7421 // because the validation above means you can only get here if the level 7422 // is already a matching compressed format and in that case 7423 // CompressedTexImage2D already cleared the texture. 7424 glCompressedTexSubImage2D( 7425 target, level, xoffset, yoffset, width, height, format, image_size, data); 7426} 7427 7428static void Clip( 7429 GLint start, GLint range, GLint sourceRange, 7430 GLint* out_start, GLint* out_range) { 7431 DCHECK(out_start); 7432 DCHECK(out_range); 7433 if (start < 0) { 7434 range += start; 7435 start = 0; 7436 } 7437 GLint end = start + range; 7438 if (end > sourceRange) { 7439 range -= end - sourceRange; 7440 } 7441 *out_start = start; 7442 *out_range = range; 7443} 7444 7445void GLES2DecoderImpl::DoCopyTexImage2D( 7446 GLenum target, 7447 GLint level, 7448 GLenum internal_format, 7449 GLint x, 7450 GLint y, 7451 GLsizei width, 7452 GLsizei height, 7453 GLint border) { 7454 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 7455 if (!info) { 7456 SetGLError(GL_INVALID_OPERATION, 7457 "glCopyTexImage2D", "unknown texture for target"); 7458 return; 7459 } 7460 if (info->IsImmutable()) { 7461 SetGLError(GL_INVALID_OPERATION, 7462 "glCopyTexImage2D", "texture is immutable"); 7463 } 7464 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) || 7465 border != 0) { 7466 SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range"); 7467 return; 7468 } 7469 if (!ValidateTextureParameters( 7470 "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) { 7471 return; 7472 } 7473 7474 // Check we have compatible formats. 7475 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); 7476 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); 7477 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format); 7478 7479 if ((channels_needed & channels_exist) != channels_needed) { 7480 SetGLError(GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format"); 7481 return; 7482 } 7483 7484 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { 7485 SetGLError( 7486 GL_INVALID_OPERATION, 7487 "glCopyImage2D", "can not be used with depth or stencil textures"); 7488 return; 7489 } 7490 7491 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) { 7492 return; 7493 } 7494 7495 CopyRealGLErrorsToWrapper(); 7496 ScopedResolvedFrameBufferBinder binder(this, false, true); 7497 gfx::Size size = GetBoundReadFrameBufferSize(); 7498 7499 if (info->IsAttachedToFramebuffer()) { 7500 clear_state_dirty_ = true; 7501 // TODO(gman): If textures tracked which framebuffers they were attached to 7502 // we could just mark those framebuffers as not complete. 7503 framebuffer_manager()->IncFramebufferStateChangeCount(); 7504 } 7505 7506 // Clip to size to source dimensions 7507 GLint copyX = 0; 7508 GLint copyY = 0; 7509 GLint copyWidth = 0; 7510 GLint copyHeight = 0; 7511 Clip(x, width, size.width(), ©X, ©Width); 7512 Clip(y, height, size.height(), ©Y, ©Height); 7513 7514 if (copyX != x || 7515 copyY != y || 7516 copyWidth != width || 7517 copyHeight != height) { 7518 // some part was clipped so clear the texture. 7519 if (!ClearLevel( 7520 info->service_id(), info->target(), 7521 target, level, internal_format, GL_UNSIGNED_BYTE, width, height, 7522 info->IsImmutable())) { 7523 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big"); 7524 return; 7525 } 7526 if (copyHeight > 0 && copyWidth > 0) { 7527 GLint dx = copyX - x; 7528 GLint dy = copyY - y; 7529 GLint destX = dx; 7530 GLint destY = dy; 7531 glCopyTexSubImage2D(target, level, 7532 destX, destY, copyX, copyY, 7533 copyWidth, copyHeight); 7534 } 7535 } else { 7536 glCopyTexImage2D(target, level, internal_format, 7537 copyX, copyY, copyWidth, copyHeight, border); 7538 } 7539 GLenum error = PeekGLError(); 7540 if (error == GL_NO_ERROR) { 7541 texture_manager()->SetLevelInfo( 7542 info, target, level, internal_format, width, height, 1, 7543 border, internal_format, GL_UNSIGNED_BYTE, true); 7544 } 7545} 7546 7547void GLES2DecoderImpl::DoCopyTexSubImage2D( 7548 GLenum target, 7549 GLint level, 7550 GLint xoffset, 7551 GLint yoffset, 7552 GLint x, 7553 GLint y, 7554 GLsizei width, 7555 GLsizei height) { 7556 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 7557 if (!info) { 7558 SetGLError(GL_INVALID_OPERATION, 7559 "glCopyTexSubImage2D", "unknown texture for target"); 7560 return; 7561 } 7562 GLenum type = 0; 7563 GLenum format = 0; 7564 if (!info->GetLevelType(target, level, &type, &format) || 7565 !info->ValidForTexture( 7566 target, level, xoffset, yoffset, width, height, format, type)) { 7567 SetGLError(GL_INVALID_VALUE, 7568 "glCopyTexSubImage2D", "bad dimensions."); 7569 return; 7570 } 7571 7572 // Check we have compatible formats. 7573 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); 7574 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); 7575 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format); 7576 7577 if (!channels_needed || 7578 (channels_needed & channels_exist) != channels_needed) { 7579 SetGLError( 7580 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format"); 7581 return; 7582 } 7583 7584 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { 7585 SetGLError( 7586 GL_INVALID_OPERATION, 7587 "glCopySubImage2D", "can not be used with depth or stencil textures"); 7588 return; 7589 } 7590 7591 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) { 7592 return; 7593 } 7594 7595 ScopedResolvedFrameBufferBinder binder(this, false, true); 7596 gfx::Size size = GetBoundReadFrameBufferSize(); 7597 GLint copyX = 0; 7598 GLint copyY = 0; 7599 GLint copyWidth = 0; 7600 GLint copyHeight = 0; 7601 Clip(x, width, size.width(), ©X, ©Width); 7602 Clip(y, height, size.height(), ©Y, ©Height); 7603 7604 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { 7605 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big"); 7606 return; 7607 } 7608 7609 if (copyX != x || 7610 copyY != y || 7611 copyWidth != width || 7612 copyHeight != height) { 7613 // some part was clipped so clear the sub rect. 7614 uint32 pixels_size = 0; 7615 if (!GLES2Util::ComputeImageDataSizes( 7616 width, height, format, type, state_.unpack_alignment, &pixels_size, 7617 NULL, NULL)) { 7618 SetGLError( 7619 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large"); 7620 return; 7621 } 7622 scoped_array<char> zero(new char[pixels_size]); 7623 memset(zero.get(), 0, pixels_size); 7624 glTexSubImage2D( 7625 target, level, xoffset, yoffset, width, height, 7626 format, type, zero.get()); 7627 } 7628 7629 if (copyHeight > 0 && copyWidth > 0) { 7630 GLint dx = copyX - x; 7631 GLint dy = copyY - y; 7632 GLint destX = xoffset + dx; 7633 GLint destY = yoffset + dy; 7634 glCopyTexSubImage2D(target, level, 7635 destX, destY, copyX, copyY, 7636 copyWidth, copyHeight); 7637 } 7638} 7639 7640void GLES2DecoderImpl::DoTexSubImage2D( 7641 GLenum target, 7642 GLint level, 7643 GLint xoffset, 7644 GLint yoffset, 7645 GLsizei width, 7646 GLsizei height, 7647 GLenum format, 7648 GLenum type, 7649 const void * data) { 7650 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 7651 if (!info) { 7652 SetGLError(GL_INVALID_OPERATION, 7653 "glTexSubImage2D", "unknown texture for target"); 7654 return; 7655 } 7656 GLenum current_type = 0; 7657 GLenum internal_format = 0; 7658 if (!info->GetLevelType(target, level, ¤t_type, &internal_format)) { 7659 SetGLError( 7660 GL_INVALID_OPERATION, "glTexSubImage2D", "level does not exist."); 7661 return; 7662 } 7663 if (format != internal_format) { 7664 SetGLError(GL_INVALID_OPERATION, 7665 "glTexSubImage2D", "format does not match internal format."); 7666 return; 7667 } 7668 if (type != current_type) { 7669 SetGLError(GL_INVALID_OPERATION, 7670 "glTexSubImage2D", "type does not match type of texture."); 7671 return; 7672 } 7673 7674 if (!info->ValidForTexture( 7675 target, level, xoffset, yoffset, width, height, format, type)) { 7676 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "bad dimensions."); 7677 return; 7678 } 7679 7680 if ((GLES2Util::GetChannelsForFormat(format) & 7681 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { 7682 SetGLError( 7683 GL_INVALID_OPERATION, 7684 "glTexSubImage2D", "can not supply data for depth or stencil textures"); 7685 return; 7686 } 7687 7688 GLsizei tex_width = 0; 7689 GLsizei tex_height = 0; 7690 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height); 7691 DCHECK(ok); 7692 if (xoffset != 0 || yoffset != 0 || 7693 width != tex_width || height != tex_height) { 7694 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { 7695 SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big"); 7696 return; 7697 } 7698 ScopedTextureUploadTimer timer(this); 7699 glTexSubImage2D( 7700 target, level, xoffset, yoffset, width, height, format, type, data); 7701 return; 7702 } 7703 7704 if (teximage2d_faster_than_texsubimage2d_ && !info->IsImmutable()) { 7705 ScopedTextureUploadTimer timer(this); 7706 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the 7707 // same as internal_foramt. If that changes we'll need to look them up. 7708 WrappedTexImage2D( 7709 target, level, format, width, height, 0, format, type, data); 7710 } else { 7711 ScopedTextureUploadTimer timer(this); 7712 glTexSubImage2D( 7713 target, level, xoffset, yoffset, width, height, format, type, data); 7714 } 7715 texture_manager()->SetLevelCleared(info, target, level); 7716} 7717 7718error::Error GLES2DecoderImpl::HandleTexSubImage2D( 7719 uint32 immediate_data_size, const gles2::TexSubImage2D& c) { 7720 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D"); 7721 GLboolean internal = static_cast<GLboolean>(c.internal); 7722 if (internal == GL_TRUE && tex_image_2d_failed_) 7723 return error::kNoError; 7724 7725 GLenum target = static_cast<GLenum>(c.target); 7726 GLint level = static_cast<GLint>(c.level); 7727 GLint xoffset = static_cast<GLint>(c.xoffset); 7728 GLint yoffset = static_cast<GLint>(c.yoffset); 7729 GLsizei width = static_cast<GLsizei>(c.width); 7730 GLsizei height = static_cast<GLsizei>(c.height); 7731 GLenum format = static_cast<GLenum>(c.format); 7732 GLenum type = static_cast<GLenum>(c.type); 7733 uint32 data_size; 7734 if (!GLES2Util::ComputeImageDataSizes( 7735 width, height, format, type, state_.unpack_alignment, &data_size, 7736 NULL, NULL)) { 7737 return error::kOutOfBounds; 7738 } 7739 const void* pixels = GetSharedMemoryAs<const void*>( 7740 c.pixels_shm_id, c.pixels_shm_offset, data_size); 7741 if (!validators_->texture_target.IsValid(target)) { 7742 SetGLErrorInvalidEnum("glTexSubImage2D", target, "target"); 7743 return error::kNoError; 7744 } 7745 if (width < 0) { 7746 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "width < 0"); 7747 return error::kNoError; 7748 } 7749 if (height < 0) { 7750 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "height < 0"); 7751 return error::kNoError; 7752 } 7753 if (!validators_->texture_format.IsValid(format)) { 7754 SetGLErrorInvalidEnum("glTexSubImage2D", format, "format"); 7755 return error::kNoError; 7756 } 7757 if (!validators_->pixel_type.IsValid(type)) { 7758 SetGLErrorInvalidEnum("glTexSubImage2D", type, "type"); 7759 return error::kNoError; 7760 } 7761 if (pixels == NULL) { 7762 return error::kOutOfBounds; 7763 } 7764 DoTexSubImage2D( 7765 target, level, xoffset, yoffset, width, height, format, type, pixels); 7766 return error::kNoError; 7767} 7768 7769error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate( 7770 uint32 immediate_data_size, const gles2::TexSubImage2DImmediate& c) { 7771 GLboolean internal = static_cast<GLboolean>(c.internal); 7772 if (internal == GL_TRUE && tex_image_2d_failed_) 7773 return error::kNoError; 7774 7775 GLenum target = static_cast<GLenum>(c.target); 7776 GLint level = static_cast<GLint>(c.level); 7777 GLint xoffset = static_cast<GLint>(c.xoffset); 7778 GLint yoffset = static_cast<GLint>(c.yoffset); 7779 GLsizei width = static_cast<GLsizei>(c.width); 7780 GLsizei height = static_cast<GLsizei>(c.height); 7781 GLenum format = static_cast<GLenum>(c.format); 7782 GLenum type = static_cast<GLenum>(c.type); 7783 uint32 data_size; 7784 if (!GLES2Util::ComputeImageDataSizes( 7785 width, height, format, type, state_.unpack_alignment, &data_size, 7786 NULL, NULL)) { 7787 return error::kOutOfBounds; 7788 } 7789 const void* pixels = GetImmediateDataAs<const void*>( 7790 c, data_size, immediate_data_size); 7791 if (!validators_->texture_target.IsValid(target)) { 7792 SetGLErrorInvalidEnum("glTexSubImage2D", target, "target"); 7793 return error::kNoError; 7794 } 7795 if (width < 0) { 7796 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "width < 0"); 7797 return error::kNoError; 7798 } 7799 if (height < 0) { 7800 SetGLError(GL_INVALID_VALUE, "glTexSubImage2D", "height < 0"); 7801 return error::kNoError; 7802 } 7803 if (!validators_->texture_format.IsValid(format)) { 7804 SetGLErrorInvalidEnum("glTexSubImage2D", format, "format"); 7805 return error::kNoError; 7806 } 7807 if (!validators_->pixel_type.IsValid(type)) { 7808 SetGLErrorInvalidEnum("glTexSubImage2D", type, "type"); 7809 return error::kNoError; 7810 } 7811 if (pixels == NULL) { 7812 return error::kOutOfBounds; 7813 } 7814 DoTexSubImage2D( 7815 target, level, xoffset, yoffset, width, height, format, type, pixels); 7816 return error::kNoError; 7817} 7818 7819error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv( 7820 uint32 immediate_data_size, const gles2::GetVertexAttribPointerv& c) { 7821 GLuint index = static_cast<GLuint>(c.index); 7822 GLenum pname = static_cast<GLenum>(c.pname); 7823 typedef gles2::GetVertexAttribPointerv::Result Result; 7824 Result* result = GetSharedMemoryAs<Result*>( 7825 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1)); 7826 if (!result) { 7827 return error::kOutOfBounds; 7828 } 7829 // Check that the client initialized the result. 7830 if (result->size != 0) { 7831 return error::kInvalidArguments; 7832 } 7833 if (!validators_->vertex_pointer.IsValid(pname)) { 7834 SetGLErrorInvalidEnum("glGetVertexAttribPointerv", pname, "pname"); 7835 return error::kNoError; 7836 } 7837 if (index >= group_->max_vertex_attribs()) { 7838 SetGLError(GL_INVALID_VALUE, 7839 "glGetVertexAttribPointerv", "index out of range."); 7840 return error::kNoError; 7841 } 7842 result->SetNumResults(1); 7843 *result->GetData() = 7844 state_.vertex_attrib_manager->GetVertexAttribInfo(index)->offset(); 7845 return error::kNoError; 7846} 7847 7848bool GLES2DecoderImpl::GetUniformSetup( 7849 GLuint program, GLint fake_location, 7850 uint32 shm_id, uint32 shm_offset, 7851 error::Error* error, GLint* real_location, 7852 GLuint* service_id, void** result_pointer, GLenum* result_type) { 7853 DCHECK(error); 7854 DCHECK(service_id); 7855 DCHECK(result_pointer); 7856 DCHECK(result_type); 7857 DCHECK(real_location); 7858 *error = error::kNoError; 7859 // Make sure we have enough room for the result on failure. 7860 SizedResult<GLint>* result; 7861 result = GetSharedMemoryAs<SizedResult<GLint>*>( 7862 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0)); 7863 if (!result) { 7864 *error = error::kOutOfBounds; 7865 return false; 7866 } 7867 *result_pointer = result; 7868 // Set the result size to 0 so the client does not have to check for success. 7869 result->SetNumResults(0); 7870 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( 7871 program, "glGetUniform"); 7872 if (!info) { 7873 return false; 7874 } 7875 if (!info->IsValid()) { 7876 // Program was not linked successfully. (ie, glLinkProgram) 7877 SetGLError(GL_INVALID_OPERATION, "glGetUniform", "program not linked"); 7878 return false; 7879 } 7880 *service_id = info->service_id(); 7881 GLint array_index = -1; 7882 const ProgramManager::ProgramInfo::UniformInfo* uniform_info = 7883 info->GetUniformInfoByFakeLocation( 7884 fake_location, real_location, &array_index); 7885 if (!uniform_info) { 7886 // No such location. 7887 SetGLError(GL_INVALID_OPERATION, "glGetUniform", "unknown location"); 7888 return false; 7889 } 7890 GLenum type = uniform_info->type; 7891 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type); 7892 if (size == 0) { 7893 SetGLError(GL_INVALID_OPERATION, "glGetUniform", "unknown type"); 7894 return false; 7895 } 7896 result = GetSharedMemoryAs<SizedResult<GLint>*>( 7897 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size)); 7898 if (!result) { 7899 *error = error::kOutOfBounds; 7900 return false; 7901 } 7902 result->size = size; 7903 *result_type = type; 7904 return true; 7905} 7906 7907error::Error GLES2DecoderImpl::HandleGetUniformiv( 7908 uint32 immediate_data_size, const gles2::GetUniformiv& c) { 7909 GLuint program = c.program; 7910 GLint fake_location = c.location; 7911 GLuint service_id; 7912 GLenum result_type; 7913 GLint real_location = -1; 7914 Error error; 7915 void* result; 7916 if (GetUniformSetup( 7917 program, fake_location, c.params_shm_id, c.params_shm_offset, 7918 &error, &real_location, &service_id, &result, &result_type)) { 7919 glGetUniformiv( 7920 service_id, real_location, 7921 static_cast<gles2::GetUniformiv::Result*>(result)->GetData()); 7922 } 7923 return error; 7924} 7925 7926error::Error GLES2DecoderImpl::HandleGetUniformfv( 7927 uint32 immediate_data_size, const gles2::GetUniformfv& c) { 7928 GLuint program = c.program; 7929 GLint fake_location = c.location; 7930 GLuint service_id; 7931 GLint real_location = -1; 7932 Error error; 7933 typedef gles2::GetUniformfv::Result Result; 7934 Result* result; 7935 GLenum result_type; 7936 if (GetUniformSetup( 7937 program, fake_location, c.params_shm_id, c.params_shm_offset, 7938 &error, &real_location, &service_id, 7939 reinterpret_cast<void**>(&result), &result_type)) { 7940 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 || 7941 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) { 7942 GLsizei num_values = result->GetNumResults(); 7943 scoped_array<GLint> temp(new GLint[num_values]); 7944 glGetUniformiv(service_id, real_location, temp.get()); 7945 GLfloat* dst = result->GetData(); 7946 for (GLsizei ii = 0; ii < num_values; ++ii) { 7947 dst[ii] = (temp[ii] != 0); 7948 } 7949 } else { 7950 glGetUniformfv(service_id, real_location, result->GetData()); 7951 } 7952 } 7953 return error; 7954} 7955 7956error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat( 7957 uint32 immediate_data_size, const gles2::GetShaderPrecisionFormat& c) { 7958 GLenum shader_type = static_cast<GLenum>(c.shadertype); 7959 GLenum precision_type = static_cast<GLenum>(c.precisiontype); 7960 typedef gles2::GetShaderPrecisionFormat::Result Result; 7961 Result* result = GetSharedMemoryAs<Result*>( 7962 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 7963 if (!result) { 7964 return error::kOutOfBounds; 7965 } 7966 // Check that the client initialized the result. 7967 if (result->success != 0) { 7968 return error::kInvalidArguments; 7969 } 7970 if (!validators_->shader_type.IsValid(shader_type)) { 7971 SetGLErrorInvalidEnum( 7972 "glGetShaderPrecisionFormat", shader_type, "shader_type"); 7973 return error::kNoError; 7974 } 7975 if (!validators_->shader_precision.IsValid(precision_type)) { 7976 SetGLErrorInvalidEnum( 7977 "glGetShaderPrecisionFormat", precision_type, "precision_type"); 7978 return error::kNoError; 7979 } 7980 7981 result->success = 1; // true 7982 switch (precision_type) { 7983 case GL_LOW_INT: 7984 case GL_MEDIUM_INT: 7985 case GL_HIGH_INT: 7986 // These values are for a 32-bit twos-complement integer format. 7987 result->min_range = 31; 7988 result->max_range = 30; 7989 result->precision = 0; 7990 break; 7991 case GL_LOW_FLOAT: 7992 case GL_MEDIUM_FLOAT: 7993 case GL_HIGH_FLOAT: 7994 // These values are for an IEEE single-precision floating-point format. 7995 result->min_range = 127; 7996 result->max_range = 127; 7997 result->precision = 23; 7998 break; 7999 default: 8000 NOTREACHED(); 8001 break; 8002 } 8003 return error::kNoError; 8004} 8005 8006error::Error GLES2DecoderImpl::HandleGetAttachedShaders( 8007 uint32 immediate_data_size, const gles2::GetAttachedShaders& c) { 8008 uint32 result_size = c.result_size; 8009 GLuint program = static_cast<GLuint>(c.program); 8010 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( 8011 program, "glGetAttachedShaders"); 8012 if (!info) { 8013 return error::kNoError; 8014 } 8015 typedef gles2::GetAttachedShaders::Result Result; 8016 uint32 max_count = Result::ComputeMaxResults(result_size); 8017 Result* result = GetSharedMemoryAs<Result*>( 8018 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count)); 8019 if (!result) { 8020 return error::kOutOfBounds; 8021 } 8022 // Check that the client initialized the result. 8023 if (result->size != 0) { 8024 return error::kInvalidArguments; 8025 } 8026 GLsizei count = 0; 8027 glGetAttachedShaders( 8028 info->service_id(), max_count, &count, result->GetData()); 8029 for (GLsizei ii = 0; ii < count; ++ii) { 8030 if (!shader_manager()->GetClientId(result->GetData()[ii], 8031 &result->GetData()[ii])) { 8032 NOTREACHED(); 8033 return error::kGenericError; 8034 } 8035 } 8036 result->SetNumResults(count); 8037 return error::kNoError; 8038} 8039 8040error::Error GLES2DecoderImpl::HandleGetActiveUniform( 8041 uint32 immediate_data_size, const gles2::GetActiveUniform& c) { 8042 GLuint program = c.program; 8043 GLuint index = c.index; 8044 uint32 name_bucket_id = c.name_bucket_id; 8045 typedef gles2::GetActiveUniform::Result Result; 8046 Result* result = GetSharedMemoryAs<Result*>( 8047 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 8048 if (!result) { 8049 return error::kOutOfBounds; 8050 } 8051 // Check that the client initialized the result. 8052 if (result->success != 0) { 8053 return error::kInvalidArguments; 8054 } 8055 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( 8056 program, "glGetActiveUniform"); 8057 if (!info) { 8058 return error::kNoError; 8059 } 8060 const ProgramManager::ProgramInfo::UniformInfo* uniform_info = 8061 info->GetUniformInfo(index); 8062 if (!uniform_info) { 8063 SetGLError(GL_INVALID_VALUE, "glGetActiveUniform", "index out of range"); 8064 return error::kNoError; 8065 } 8066 result->success = 1; // true. 8067 result->size = uniform_info->size; 8068 result->type = uniform_info->type; 8069 Bucket* bucket = CreateBucket(name_bucket_id); 8070 bucket->SetFromString(uniform_info->name.c_str()); 8071 return error::kNoError; 8072} 8073 8074error::Error GLES2DecoderImpl::HandleGetActiveAttrib( 8075 uint32 immediate_data_size, const gles2::GetActiveAttrib& c) { 8076 GLuint program = c.program; 8077 GLuint index = c.index; 8078 uint32 name_bucket_id = c.name_bucket_id; 8079 typedef gles2::GetActiveAttrib::Result Result; 8080 Result* result = GetSharedMemoryAs<Result*>( 8081 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 8082 if (!result) { 8083 return error::kOutOfBounds; 8084 } 8085 // Check that the client initialized the result. 8086 if (result->success != 0) { 8087 return error::kInvalidArguments; 8088 } 8089 ProgramManager::ProgramInfo* info = GetProgramInfoNotShader( 8090 program, "glGetActiveAttrib"); 8091 if (!info) { 8092 return error::kNoError; 8093 } 8094 const ProgramManager::ProgramInfo::VertexAttribInfo* attrib_info = 8095 info->GetAttribInfo(index); 8096 if (!attrib_info) { 8097 SetGLError(GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range"); 8098 return error::kNoError; 8099 } 8100 result->success = 1; // true. 8101 result->size = attrib_info->size; 8102 result->type = attrib_info->type; 8103 Bucket* bucket = CreateBucket(name_bucket_id); 8104 bucket->SetFromString(attrib_info->name.c_str()); 8105 return error::kNoError; 8106} 8107 8108error::Error GLES2DecoderImpl::HandleShaderBinary( 8109 uint32 immediate_data_size, const gles2::ShaderBinary& c) { 8110#if 1 // No binary shader support. 8111 SetGLError(GL_INVALID_OPERATION, "glShaderBinary", "not supported"); 8112 return error::kNoError; 8113#else 8114 GLsizei n = static_cast<GLsizei>(c.n); 8115 if (n < 0) { 8116 SetGLError(GL_INVALID_VALUE, "glShaderBinary", "n < 0"); 8117 return error::kNoError; 8118 } 8119 GLsizei length = static_cast<GLsizei>(c.length); 8120 if (length < 0) { 8121 SetGLError(GL_INVALID_VALUE, "glShaderBinary", "length < 0"); 8122 return error::kNoError; 8123 } 8124 uint32 data_size; 8125 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) { 8126 return error::kOutOfBounds; 8127 } 8128 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>( 8129 c.shaders_shm_id, c.shaders_shm_offset, data_size); 8130 GLenum binaryformat = static_cast<GLenum>(c.binaryformat); 8131 const void* binary = GetSharedMemoryAs<const void*>( 8132 c.binary_shm_id, c.binary_shm_offset, length); 8133 if (shaders == NULL || binary == NULL) { 8134 return error::kOutOfBounds; 8135 } 8136 scoped_array<GLuint> service_ids(new GLuint[n]); 8137 for (GLsizei ii = 0; ii < n; ++ii) { 8138 ShaderManager::ShaderInfo* info = GetShaderInfo(shaders[ii]); 8139 if (!info) { 8140 SetGLError(GL_INVALID_VALUE, "glShaderBinary", "unknown shader"); 8141 return error::kNoError; 8142 } 8143 service_ids[ii] = info->service_id(); 8144 } 8145 // TODO(gman): call glShaderBinary 8146 return error::kNoError; 8147#endif 8148} 8149 8150error::Error GLES2DecoderImpl::HandleSwapBuffers( 8151 uint32 immediate_data_size, const gles2::SwapBuffers& c) { 8152 bool is_offscreen = !!offscreen_target_frame_buffer_.get(); 8153 if (!is_offscreen && surface_->DeferSwapBuffers()) { 8154 return error::kDeferCommandUntilLater; 8155 } 8156 8157 int this_frame_number = frame_number_++; 8158 // TRACE_EVENT for gpu tests: 8159 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency", 8160 "GLImpl", static_cast<int>(gfx::GetGLImplementation()), 8161 "width", (is_offscreen ? offscreen_size_.width() : 8162 surface_->GetSize().width())); 8163 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleSwapBuffers", 8164 "offscreen", is_offscreen, 8165 "frame", this_frame_number); 8166 // If offscreen then don't actually SwapBuffers to the display. Just copy 8167 // the rendered frame to another frame buffer. 8168 if (is_offscreen) { 8169 TRACE_EVENT2("gpu", "Offscreen", 8170 "width", offscreen_size_.width(), "height", offscreen_size_.height()); 8171 if (offscreen_size_ != offscreen_saved_color_texture_->size()) { 8172 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557, 8173 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will 8174 // fix this. 8175 if (workarounds().needs_offscreen_buffer_workaround) { 8176 offscreen_saved_frame_buffer_->Create(); 8177 glFinish(); 8178 } 8179 8180 // Allocate the offscreen saved color texture. 8181 DCHECK(offscreen_saved_color_format_); 8182 offscreen_saved_color_texture_->AllocateStorage( 8183 offscreen_size_, offscreen_saved_color_format_); 8184 8185 offscreen_saved_frame_buffer_->AttachRenderTexture( 8186 offscreen_saved_color_texture_.get()); 8187 if (offscreen_saved_frame_buffer_->CheckStatus() != 8188 GL_FRAMEBUFFER_COMPLETE) { 8189 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed " 8190 << "because offscreen saved FBO was incomplete."; 8191 return error::kLostContext; 8192 } 8193 8194 // Clear the offscreen color texture. 8195 // TODO(piman): Is this still necessary? 8196 { 8197 ScopedFrameBufferBinder binder(this, 8198 offscreen_saved_frame_buffer_->id()); 8199 glClearColor(0, 0, 0, 0); 8200 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 8201 glDisable(GL_SCISSOR_TEST); 8202 glClear(GL_COLOR_BUFFER_BIT); 8203 RestoreClearState(); 8204 } 8205 8206 UpdateParentTextureInfo(); 8207 } 8208 8209 ScopedGLErrorSuppressor suppressor(this); 8210 8211 if (IsOffscreenBufferMultisampled()) { 8212 // For multisampled buffers, resolve the frame buffer. 8213 ScopedResolvedFrameBufferBinder binder(this, true, false); 8214 return error::kNoError; 8215 } else { 8216 ScopedFrameBufferBinder binder(this, 8217 offscreen_target_frame_buffer_->id()); 8218 8219 if (offscreen_target_buffer_preserved_) { 8220 // Copy the target frame buffer to the saved offscreen texture. 8221 offscreen_saved_color_texture_->Copy( 8222 offscreen_saved_color_texture_->size(), 8223 offscreen_saved_color_format_); 8224 } else { 8225 // Flip the textures in the parent context via the texture manager. 8226 if (!!offscreen_saved_color_texture_info_.get()) 8227 offscreen_saved_color_texture_info_-> 8228 SetServiceId(offscreen_target_color_texture_->id()); 8229 8230 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_); 8231 offscreen_target_frame_buffer_->AttachRenderTexture( 8232 offscreen_target_color_texture_.get()); 8233 } 8234 8235 // Ensure the side effects of the copy are visible to the parent 8236 // context. There is no need to do this for ANGLE because it uses a 8237 // single D3D device for all contexts. 8238 if (!IsAngle()) 8239 glFlush(); 8240 return error::kNoError; 8241 } 8242 } else { 8243 TRACE_EVENT2("gpu", "Onscreen", 8244 "width", surface_->GetSize().width(), 8245 "height", surface_->GetSize().height()); 8246 if (!surface_->SwapBuffers()) { 8247 LOG(ERROR) << "Context lost because SwapBuffers failed."; 8248 return error::kLostContext; 8249 } 8250 } 8251 8252 return error::kNoError; 8253} 8254 8255error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM( 8256 uint32 immediate_data_size, const gles2::EnableFeatureCHROMIUM& c) { 8257 Bucket* bucket = GetBucket(c.bucket_id); 8258 if (!bucket || bucket->size() == 0) { 8259 return error::kInvalidArguments; 8260 } 8261 typedef gles2::EnableFeatureCHROMIUM::Result Result; 8262 Result* result = GetSharedMemoryAs<Result*>( 8263 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 8264 if (!result) { 8265 return error::kOutOfBounds; 8266 } 8267 // Check that the client initialized the result. 8268 if (*result != 0) { 8269 return error::kInvalidArguments; 8270 } 8271 std::string feature_str; 8272 if (!bucket->GetAsString(&feature_str)) { 8273 return error::kInvalidArguments; 8274 } 8275 8276 // TODO(gman): make this some kind of table to function pointer thingy. 8277 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) { 8278 buffer_manager()->set_allow_buffers_on_multiple_targets(true); 8279 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) { 8280 buffer_manager()->set_allow_buffers_on_multiple_targets(true); 8281 // TODO(gman): decide how to remove the need for this const_cast. 8282 // I could make validators_ non const but that seems bad as this is the only 8283 // place it is needed. I could make some special friend class of validators 8284 // just to allow this to set them. That seems silly. I could refactor this 8285 // code to use the extension mechanism or the initialization attributes to 8286 // turn this feature on. Given that the only real point of this is to make 8287 // the conformance tests pass and given that there is lots of real work that 8288 // needs to be done it seems like refactoring for one to one of those 8289 // methods is a very low priority. 8290 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED); 8291 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) { 8292 force_webgl_glsl_validation_ = true; 8293 InitializeShaderTranslator(); 8294 } else { 8295 return error::kNoError; 8296 } 8297 8298 *result = 1; // true. 8299 return error::kNoError; 8300} 8301 8302error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM( 8303 uint32 immediate_data_size, 8304 const gles2::GetRequestableExtensionsCHROMIUM& c) { 8305 Bucket* bucket = CreateBucket(c.bucket_id); 8306 FeatureInfo::Ref info(new FeatureInfo()); 8307 info->Initialize(disallowed_features_, NULL); 8308 bucket->SetFromString(info->extensions().c_str()); 8309 return error::kNoError; 8310} 8311 8312error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM( 8313 uint32 immediate_data_size, const gles2::RequestExtensionCHROMIUM& c) { 8314 Bucket* bucket = GetBucket(c.bucket_id); 8315 if (!bucket || bucket->size() == 0) { 8316 return error::kInvalidArguments; 8317 } 8318 std::string feature_str; 8319 if (!bucket->GetAsString(&feature_str)) { 8320 return error::kInvalidArguments; 8321 } 8322 8323 bool std_derivatives_enabled = features().oes_standard_derivatives; 8324 bool webglsl_enabled = features().chromium_webglsl; 8325 8326 feature_info_->AddFeatures(feature_str.c_str()); 8327 8328 bool initialization_required = false; 8329 if (force_webgl_glsl_validation_ && !derivatives_explicitly_enabled_) { 8330 size_t derivatives_offset = feature_str.find(kOESDerivativeExtension); 8331 if (std::string::npos != derivatives_offset) { 8332 derivatives_explicitly_enabled_ = true; 8333 initialization_required = true; 8334 } 8335 } 8336 8337 // If we just enabled a feature which affects the shader translator, 8338 // we may need to re-initialize it. 8339 if (std_derivatives_enabled != features().oes_standard_derivatives || 8340 webglsl_enabled != features().chromium_webglsl || 8341 initialization_required) { 8342 InitializeShaderTranslator(); 8343 } 8344 8345 UpdateCapabilities(); 8346 8347 return error::kNoError; 8348} 8349 8350error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM( 8351 uint32 immediate_data_size, const gles2::GetMultipleIntegervCHROMIUM& c) { 8352 GLuint count = c.count; 8353 uint32 pnames_size; 8354 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) { 8355 return error::kOutOfBounds; 8356 } 8357 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>( 8358 c.pnames_shm_id, c.pnames_shm_offset, pnames_size); 8359 if (pnames == NULL) { 8360 return error::kOutOfBounds; 8361 } 8362 8363 // We have to copy them since we use them twice so the client 8364 // can't change them between the time we validate them and the time we use 8365 // them. 8366 scoped_array<GLenum> enums(new GLenum[count]); 8367 memcpy(enums.get(), pnames, pnames_size); 8368 8369 // Count up the space needed for the result. 8370 uint32 num_results = 0; 8371 for (GLuint ii = 0; ii < count; ++ii) { 8372 uint32 num = util_.GLGetNumValuesReturned(enums[ii]); 8373 if (num == 0) { 8374 SetGLErrorInvalidEnum("glGetMulitpleCHROMIUM", enums[ii], "pname"); 8375 return error::kNoError; 8376 } 8377 // Num will never be more than 4. 8378 DCHECK_LE(num, 4u); 8379 if (!SafeAddUint32(num_results, num, &num_results)) { 8380 return error::kOutOfBounds; 8381 } 8382 } 8383 8384 uint32 result_size = 0; 8385 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) { 8386 return error::kOutOfBounds; 8387 } 8388 8389 if (result_size != static_cast<uint32>(c.size)) { 8390 SetGLError(GL_INVALID_VALUE, 8391 "glGetMulitpleCHROMIUM", "bad size GL_INVALID_VALUE"); 8392 return error::kNoError; 8393 } 8394 8395 GLint* results = GetSharedMemoryAs<GLint*>( 8396 c.results_shm_id, c.results_shm_offset, result_size); 8397 if (results == NULL) { 8398 return error::kOutOfBounds; 8399 } 8400 8401 // Check the results have been cleared in case the context was lost. 8402 for (uint32 ii = 0; ii < num_results; ++ii) { 8403 if (results[ii]) { 8404 return error::kInvalidArguments; 8405 } 8406 } 8407 8408 // Get each result. 8409 GLint* start = results; 8410 for (GLuint ii = 0; ii < count; ++ii) { 8411 GLsizei num_written = 0; 8412 if (!GetStateAsGLint(enums[ii], results, &num_written) && 8413 !GetHelper(enums[ii], results, &num_written)) { 8414 glGetIntegerv(enums[ii], results); 8415 } 8416 results += num_written; 8417 } 8418 8419 // Just to verify. Should this be a DCHECK? 8420 if (static_cast<uint32>(results - start) != num_results) { 8421 return error::kOutOfBounds; 8422 } 8423 8424 return error::kNoError; 8425} 8426 8427error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM( 8428 uint32 immediate_data_size, const gles2::GetProgramInfoCHROMIUM& c) { 8429 GLuint program = static_cast<GLuint>(c.program); 8430 uint32 bucket_id = c.bucket_id; 8431 Bucket* bucket = CreateBucket(bucket_id); 8432 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail. 8433 ProgramManager::ProgramInfo* info = NULL; 8434 info = GetProgramInfo(program); 8435 if (!info || !info->IsValid()) { 8436 return error::kNoError; 8437 } 8438 info->GetProgramInfo(program_manager(), bucket); 8439 return error::kNoError; 8440} 8441 8442error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() { 8443 switch (reset_status_) { 8444 case GL_NO_ERROR: 8445 // TODO(kbr): improve the precision of the error code in this case. 8446 // Consider delegating to context for error code if MakeCurrent fails. 8447 return error::kUnknown; 8448 case GL_GUILTY_CONTEXT_RESET_ARB: 8449 return error::kGuilty; 8450 case GL_INNOCENT_CONTEXT_RESET_ARB: 8451 return error::kInnocent; 8452 case GL_UNKNOWN_CONTEXT_RESET_ARB: 8453 return error::kUnknown; 8454 } 8455 8456 NOTREACHED(); 8457 return error::kUnknown; 8458} 8459 8460bool GLES2DecoderImpl::WasContextLost() { 8461 if (context_->WasAllocatedUsingRobustnessExtension()) { 8462 GLenum status = GL_NO_ERROR; 8463 if (has_robustness_extension_) 8464 status = glGetGraphicsResetStatusARB(); 8465 if (status != GL_NO_ERROR) { 8466 // The graphics card was reset. Signal a lost context to the application. 8467 reset_status_ = status; 8468 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen") 8469 << " context lost via ARB/EXT_robustness. Reset status = 0x" 8470 << std::hex << status << std::dec; 8471 return true; 8472 } 8473 } 8474 return false; 8475} 8476 8477bool GLES2DecoderImpl::GenQueriesEXTHelper( 8478 GLsizei n, const GLuint* client_ids) { 8479 for (GLsizei ii = 0; ii < n; ++ii) { 8480 if (query_manager_->GetQuery(client_ids[ii])) { 8481 return false; 8482 } 8483 } 8484 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT 8485 return true; 8486} 8487 8488void GLES2DecoderImpl::DeleteQueriesEXTHelper( 8489 GLsizei n, const GLuint* client_ids) { 8490 for (GLsizei ii = 0; ii < n; ++ii) { 8491 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]); 8492 if (query && !query->IsDeleted()) { 8493 if (query == state_.current_query) { 8494 state_.current_query = NULL; 8495 } 8496 query->Destroy(true); 8497 query_manager_->RemoveQuery(client_ids[ii]); 8498 } 8499 } 8500} 8501 8502bool GLES2DecoderImpl::ProcessPendingQueries() { 8503 if (query_manager_.get() == NULL) { 8504 return false; 8505 } 8506 if (!query_manager_->ProcessPendingQueries()) { 8507 current_decoder_error_ = error::kOutOfBounds; 8508 } 8509 return query_manager_->HavePendingQueries(); 8510} 8511 8512error::Error GLES2DecoderImpl::HandleBeginQueryEXT( 8513 uint32 immediate_data_size, const gles2::BeginQueryEXT& c) { 8514 GLenum target = static_cast<GLenum>(c.target); 8515 GLuint client_id = static_cast<GLuint>(c.id); 8516 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id); 8517 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset); 8518 8519 switch (target) { 8520 case GL_COMMANDS_ISSUED_CHROMIUM: 8521 case GL_LATENCY_QUERY_CHROMIUM: 8522 break; 8523 default: 8524 if (!features().occlusion_query_boolean) { 8525 SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "not enabled"); 8526 return error::kNoError; 8527 } 8528 break; 8529 } 8530 8531 if (state_.current_query) { 8532 SetGLError( 8533 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress"); 8534 return error::kNoError; 8535 } 8536 8537 if (client_id == 0) { 8538 SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0"); 8539 return error::kNoError; 8540 } 8541 8542 QueryManager::Query* query = query_manager_->GetQuery(client_id); 8543 if (!query) { 8544 // TODO(gman): Decide if we need this check. 8545 // 8546 // Checks id was made by glGenQueries 8547 // 8548 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT 8549 // for all Query ids but from the POV of the command buffer service maybe 8550 // you don't. 8551 // 8552 // The client can enforce this. I don't think the service cares. 8553 // 8554 // IdAllocatorInterface* id_allocator = 8555 // group_->GetIdAllocator(id_namespaces::kQueries); 8556 // if (!id_allocator->InUse(client_id)) { 8557 // SetGLError(GL_INVALID_OPERATION, 8558 // "glBeginQueryEXT", "id not made by glGenQueriesEXT"); 8559 // return error::kNoError; 8560 // } 8561 query = query_manager_->CreateQuery( 8562 target, client_id, sync_shm_id, sync_shm_offset); 8563 } 8564 8565 if (query->target() != target) { 8566 SetGLError( 8567 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match"); 8568 return error::kNoError; 8569 } else if (query->shm_id() != sync_shm_id || 8570 query->shm_offset() != sync_shm_offset) { 8571 DLOG(ERROR) << "Shared memory used by query not the same as before"; 8572 return error::kInvalidArguments; 8573 } 8574 8575 if (!query_manager_->BeginQuery(query)) { 8576 return error::kOutOfBounds; 8577 } 8578 8579 state_.current_query = query; 8580 return error::kNoError; 8581} 8582 8583error::Error GLES2DecoderImpl::HandleEndQueryEXT( 8584 uint32 immediate_data_size, const gles2::EndQueryEXT& c) { 8585 GLenum target = static_cast<GLenum>(c.target); 8586 uint32 submit_count = static_cast<GLuint>(c.submit_count); 8587 8588 if (!state_.current_query) { 8589 SetGLError(GL_INVALID_OPERATION, "glEndQueryEXT", "No active query"); 8590 return error::kNoError; 8591 } 8592 if (state_.current_query->target() != target) { 8593 SetGLError(GL_INVALID_OPERATION, 8594 "glEndQueryEXT", "target does not match active query"); 8595 return error::kNoError; 8596 } 8597 8598 if (!query_manager_->EndQuery(state_.current_query, submit_count)) { 8599 return error::kOutOfBounds; 8600 } 8601 8602 state_.current_query = NULL; 8603 return error::kNoError; 8604} 8605 8606bool GLES2DecoderImpl::GenVertexArraysOESHelper( 8607 GLsizei n, const GLuint* client_ids) { 8608 for (GLsizei ii = 0; ii < n; ++ii) { 8609 if (GetVertexAttribManager(client_ids[ii])) { 8610 return false; 8611 } 8612 } 8613 8614 if (!features().native_vertex_array_object) { 8615 // Emulated VAO 8616 for (GLsizei ii = 0; ii < n; ++ii) { 8617 CreateVertexAttribManager(client_ids[ii], 0); 8618 } 8619 } else { 8620 scoped_array<GLuint> service_ids(new GLuint[n]); 8621 8622 glGenVertexArraysOES(n, service_ids.get()); 8623 for (GLsizei ii = 0; ii < n; ++ii) { 8624 CreateVertexAttribManager(client_ids[ii], service_ids[ii]); 8625 } 8626 } 8627 8628 return true; 8629} 8630 8631void GLES2DecoderImpl::DeleteVertexArraysOESHelper( 8632 GLsizei n, const GLuint* client_ids) { 8633 for (GLsizei ii = 0; ii < n; ++ii) { 8634 VertexAttribManager* vao = 8635 GetVertexAttribManager(client_ids[ii]); 8636 if (vao && !vao->IsDeleted()) { 8637 if (state_.vertex_attrib_manager == vao) { 8638 state_.vertex_attrib_manager = default_vertex_attrib_manager_; 8639 } 8640 RemoveVertexAttribManager(client_ids[ii]); 8641 } 8642 } 8643} 8644 8645void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) { 8646 VertexAttribManager* vao = NULL; 8647 GLuint service_id = 0; 8648 if (client_id != 0) { 8649 vao = GetVertexAttribManager(client_id); 8650 if (!vao) { 8651 // Unlike most Bind* methods, the spec explicitly states that VertexArray 8652 // only allows names that have been previously generated. As such, we do 8653 // not generate new names here. 8654 SetGLError(GL_INVALID_OPERATION, 8655 "glBindVertexArrayOES", "" 8656 "bad vertex array id."); 8657 current_decoder_error_ = error::kNoError; 8658 return; 8659 } else { 8660 service_id = vao->service_id(); 8661 } 8662 } else { 8663 vao = default_vertex_attrib_manager_; 8664 } 8665 8666 // Only set the VAO state if it's changed 8667 if (state_.vertex_attrib_manager != vao) { 8668 state_.vertex_attrib_manager = vao; 8669 if (!features().native_vertex_array_object) { 8670 EmulateVertexArrayState(); 8671 } else { 8672 glBindVertexArrayOES(service_id); 8673 } 8674 } 8675} 8676 8677// Used when OES_vertex_array_object isn't natively supported 8678void GLES2DecoderImpl::EmulateVertexArrayState() { 8679 // Setup the Vertex attribute state 8680 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) { 8681 RestoreStateForAttrib(vv); 8682 } 8683 8684 // Setup the element buffer 8685 BufferManager::BufferInfo* element_array_buffer = 8686 state_.vertex_attrib_manager->element_array_buffer(); 8687 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 8688 element_array_buffer ? element_array_buffer->service_id() : 0); 8689} 8690 8691bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) { 8692 const VertexAttribManager* vao = 8693 GetVertexAttribManager(client_id); 8694 return vao && vao->IsValid() && !vao->IsDeleted(); 8695} 8696 8697error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM( 8698 uint32 immediate_data_size, 8699 const gles2::CreateStreamTextureCHROMIUM& c) { 8700 if (!features().chromium_stream_texture) { 8701 SetGLError(GL_INVALID_OPERATION, 8702 "glOpenStreamTextureCHROMIUM", "" 8703 "not supported."); 8704 return error::kNoError; 8705 } 8706 8707 uint32 client_id = c.client_id; 8708 typedef gles2::CreateStreamTextureCHROMIUM::Result Result; 8709 Result* result = GetSharedMemoryAs<Result*>( 8710 c.result_shm_id, c.result_shm_offset, sizeof(*result)); 8711 8712 if (!result) 8713 return error::kOutOfBounds; 8714 *result = GL_ZERO; 8715 TextureManager::TextureInfo* info = 8716 texture_manager()->GetTextureInfo(client_id); 8717 if (!info) { 8718 SetGLError(GL_INVALID_VALUE, 8719 "glCreateStreamTextureCHROMIUM", "" 8720 "bad texture id."); 8721 return error::kNoError; 8722 } 8723 8724 if (info->IsStreamTexture()) { 8725 SetGLError(GL_INVALID_OPERATION, 8726 "glCreateStreamTextureCHROMIUM", "" 8727 "is already a stream texture."); 8728 return error::kNoError; 8729 } 8730 8731 if (info->target() && info->target() != GL_TEXTURE_EXTERNAL_OES) { 8732 SetGLError(GL_INVALID_OPERATION, 8733 "glCreateStreamTextureCHROMIUM", "" 8734 "is already bound to incompatible target."); 8735 return error::kNoError; 8736 } 8737 8738 if (!stream_texture_manager_) 8739 return error::kInvalidArguments; 8740 8741 GLuint object_id = stream_texture_manager_->CreateStreamTexture( 8742 info->service_id(), client_id); 8743 8744 if (object_id) { 8745 info->SetStreamTexture(true); 8746 } else { 8747 SetGLError(GL_OUT_OF_MEMORY, 8748 "glCreateStreamTextureCHROMIUM", "" 8749 "failed to create platform texture."); 8750 } 8751 8752 *result = object_id; 8753 return error::kNoError; 8754} 8755 8756error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM( 8757 uint32 immediate_data_size, 8758 const gles2::DestroyStreamTextureCHROMIUM& c) { 8759 GLuint client_id = c.texture; 8760 TextureManager::TextureInfo* info = 8761 texture_manager()->GetTextureInfo(client_id); 8762 if (info && info->IsStreamTexture()) { 8763 if (!stream_texture_manager_) 8764 return error::kInvalidArguments; 8765 8766 stream_texture_manager_->DestroyStreamTexture(info->service_id()); 8767 info->SetStreamTexture(false); 8768 texture_manager()->SetInfoTarget(info, 0); 8769 } else { 8770 SetGLError(GL_INVALID_VALUE, 8771 "glDestroyStreamTextureCHROMIUM", "bad texture id."); 8772 } 8773 8774 return error::kNoError; 8775} 8776 8777#if defined(OS_MACOSX) 8778void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) { 8779 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find( 8780 texture_id); 8781 if (it != texture_to_io_surface_map_.end()) { 8782 // Found a previous IOSurface bound to this texture; release it. 8783 CFTypeRef surface = it->second; 8784 CFRelease(surface); 8785 texture_to_io_surface_map_.erase(it); 8786 } 8787} 8788#endif 8789 8790void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM( 8791 GLenum target, GLsizei width, GLsizei height, 8792 GLuint io_surface_id, GLuint plane) { 8793#if defined(OS_MACOSX) 8794 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) { 8795 SetGLError( 8796 GL_INVALID_OPERATION, 8797 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL."); 8798 return; 8799 } 8800 8801 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize(); 8802 if (!surface_support) { 8803 SetGLError(GL_INVALID_OPERATION, 8804 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6."); 8805 return; 8806 } 8807 8808 if (target != GL_TEXTURE_RECTANGLE_ARB) { 8809 // This might be supported in the future, and if we could require 8810 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we 8811 // could delete a lot of code. For now, perform strict validation so we 8812 // know what's going on. 8813 SetGLError( 8814 GL_INVALID_OPERATION, 8815 "glTexImageIOSurface2DCHROMIUM", 8816 "requires TEXTURE_RECTANGLE_ARB target"); 8817 return; 8818 } 8819 8820 // Default target might be conceptually valid, but disallow it to avoid 8821 // accidents. 8822 TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault( 8823 target); 8824 if (!info) { 8825 SetGLError(GL_INVALID_OPERATION, 8826 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound"); 8827 return; 8828 } 8829 8830 // Look up the new IOSurface. Note that because of asynchrony 8831 // between processes this might fail; during live resizing the 8832 // plugin process might allocate and release an IOSurface before 8833 // this process gets a chance to look it up. Hold on to any old 8834 // IOSurface in this case. 8835 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id); 8836 if (!surface) { 8837 SetGLError( 8838 GL_INVALID_OPERATION, 8839 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID"); 8840 return; 8841 } 8842 8843 // Release any IOSurface previously bound to this texture. 8844 ReleaseIOSurfaceForTexture(info->service_id()); 8845 8846 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails. 8847 texture_to_io_surface_map_.insert( 8848 std::make_pair(info->service_id(), surface)); 8849 8850 CGLContextObj context = 8851 static_cast<CGLContextObj>(context_->GetHandle()); 8852 8853 CGLError err = surface_support->CGLTexImageIOSurface2D( 8854 context, 8855 target, 8856 GL_RGBA, 8857 width, 8858 height, 8859 GL_BGRA, 8860 GL_UNSIGNED_INT_8_8_8_8_REV, 8861 surface, 8862 plane); 8863 8864 if (err != kCGLNoError) { 8865 SetGLError( 8866 GL_INVALID_OPERATION, 8867 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D"); 8868 return; 8869 } 8870 8871 texture_manager()->SetLevelInfo( 8872 info, target, 0, GL_RGBA, width, height, 1, 0, 8873 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true); 8874 8875#else 8876 SetGLError(GL_INVALID_OPERATION, 8877 "glTexImageIOSurface2DCHROMIUM", "not supported."); 8878#endif 8879} 8880 8881static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) { 8882 switch (internalformat) { 8883 case GL_RGB565: 8884 return GL_RGB; 8885 case GL_RGBA4: 8886 return GL_RGBA; 8887 case GL_RGB5_A1: 8888 return GL_RGBA; 8889 case GL_RGB8_OES: 8890 return GL_RGB; 8891 case GL_RGBA8_OES: 8892 return GL_RGBA; 8893 case GL_LUMINANCE8_ALPHA8_EXT: 8894 return GL_LUMINANCE_ALPHA; 8895 case GL_LUMINANCE8_EXT: 8896 return GL_LUMINANCE; 8897 case GL_ALPHA8_EXT: 8898 return GL_ALPHA; 8899 case GL_RGBA32F_EXT: 8900 return GL_RGBA; 8901 case GL_RGB32F_EXT: 8902 return GL_RGB; 8903 case GL_ALPHA32F_EXT: 8904 return GL_ALPHA; 8905 case GL_LUMINANCE32F_EXT: 8906 return GL_LUMINANCE; 8907 case GL_LUMINANCE_ALPHA32F_EXT: 8908 return GL_LUMINANCE_ALPHA; 8909 case GL_RGBA16F_EXT: 8910 return GL_RGBA; 8911 case GL_RGB16F_EXT: 8912 return GL_RGB; 8913 case GL_ALPHA16F_EXT: 8914 return GL_ALPHA; 8915 case GL_LUMINANCE16F_EXT: 8916 return GL_LUMINANCE; 8917 case GL_LUMINANCE_ALPHA16F_EXT: 8918 return GL_LUMINANCE_ALPHA; 8919 case GL_BGRA8_EXT: 8920 return GL_BGRA_EXT; 8921 default: 8922 return GL_NONE; 8923 } 8924} 8925 8926void GLES2DecoderImpl::DoCopyTextureCHROMIUM( 8927 GLenum target, GLuint source_id, GLuint dest_id, GLint level, 8928 GLenum internal_format) { 8929 TextureManager::TextureInfo* dest_info = GetTextureInfo(dest_id); 8930 TextureManager::TextureInfo* source_info = GetTextureInfo(source_id); 8931 8932 if (!source_info || !dest_info) { 8933 SetGLError(GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id"); 8934 return; 8935 } 8936 8937 if (GL_TEXTURE_2D != target) { 8938 SetGLError(GL_INVALID_VALUE, 8939 "glCopyTextureCHROMIUM", "invalid texture target"); 8940 return; 8941 } 8942 8943 if (dest_info->target() != GL_TEXTURE_2D || 8944 source_info->target() != GL_TEXTURE_2D) { 8945 SetGLError(GL_INVALID_VALUE, 8946 "glCopyTextureCHROMIUM", "invalid texture target binding"); 8947 return; 8948 } 8949 8950 int source_width, source_height, dest_width, dest_height; 8951 if (!source_info->GetLevelSize(GL_TEXTURE_2D, 0, &source_width, 8952 &source_height)) { 8953 SetGLError(GL_INVALID_VALUE, 8954 "glCopyTextureChromium", "source texture has no level 0"); 8955 return; 8956 } 8957 8958 // Check that this type of texture is allowed. 8959 if (!texture_manager()->ValidForTarget(GL_TEXTURE_2D, level, source_width, 8960 source_height, 1)) { 8961 SetGLError(GL_INVALID_VALUE, 8962 "glCopyTextureCHROMIUM", "Bad dimensions"); 8963 return; 8964 } 8965 8966 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is 8967 // needed because it takes 10s of milliseconds to initialize. 8968 if (!copy_texture_CHROMIUM_.get()) { 8969 CopyRealGLErrorsToWrapper(); 8970 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager()); 8971 copy_texture_CHROMIUM_->Initialize(); 8972 RestoreCurrentFramebufferBindings(); 8973 if (PeekGLError() != GL_NO_ERROR) 8974 return; 8975 } 8976 8977 GLenum dest_type; 8978 GLenum dest_internal_format; 8979 bool dest_level_defined = dest_info->GetLevelSize(GL_TEXTURE_2D, level, 8980 &dest_width, 8981 &dest_height); 8982 8983 if (dest_level_defined) { 8984 dest_info->GetLevelType(GL_TEXTURE_2D, level, &dest_type, 8985 &dest_internal_format); 8986 } else { 8987 GLenum source_internal_format; 8988 source_info->GetLevelType(GL_TEXTURE_2D, 0, &dest_type, 8989 &source_internal_format); 8990 } 8991 8992 // Resize the destination texture to the dimensions of the source texture. 8993 if (!dest_level_defined || dest_width != source_width || 8994 dest_height != source_height || 8995 dest_internal_format != internal_format) { 8996 // Ensure that the glTexImage2D succeeds. 8997 CopyRealGLErrorsToWrapper(); 8998 glBindTexture(GL_TEXTURE_2D, dest_info->service_id()); 8999 WrappedTexImage2D( 9000 GL_TEXTURE_2D, level, internal_format, source_width, source_height, 9001 0, internal_format, dest_type, NULL); 9002 GLenum error = PeekGLError(); 9003 if (error != GL_NO_ERROR) { 9004 RestoreCurrentTexture2DBindings(); 9005 return; 9006 } 9007 9008 texture_manager()->SetLevelInfo( 9009 dest_info, GL_TEXTURE_2D, level, internal_format, source_width, 9010 source_height, 1, 0, internal_format, dest_type, true); 9011 } else { 9012 texture_manager()->SetLevelCleared(dest_info, GL_TEXTURE_2D, level); 9013 } 9014 9015 clear_state_dirty_ = true; 9016 glViewport(0, 0, source_width, source_height); 9017 copy_texture_CHROMIUM_->DoCopyTexture(target, source_info->service_id(), 9018 dest_info->service_id(), level, 9019 unpack_flip_y_, 9020 unpack_premultiply_alpha_, 9021 unpack_unpremultiply_alpha_); 9022 glViewport( 9023 state_.viewport_x, state_.viewport_y, 9024 state_.viewport_width, state_.viewport_height); 9025 9026 // Restore all of the state touched by the extension. 9027 if (state_.current_program) 9028 glUseProgram(state_.current_program->service_id()); 9029 else 9030 glUseProgram(0); 9031 9032 RestoreCurrentFramebufferBindings(); 9033 RestoreCurrentTexture2DBindings(); 9034 RestoreStateForAttrib( 9035 CopyTextureCHROMIUMResourceManager::kVertexPositionAttrib); 9036 RestoreStateForAttrib( 9037 CopyTextureCHROMIUMResourceManager::kVertexTextureAttrib); 9038 9039 ApplyDirtyState(); 9040} 9041 9042static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) { 9043 switch (internalformat) { 9044 case GL_RGB565: 9045 return GL_UNSIGNED_SHORT_5_6_5; 9046 case GL_RGBA4: 9047 return GL_UNSIGNED_SHORT_4_4_4_4; 9048 case GL_RGB5_A1: 9049 return GL_UNSIGNED_SHORT_5_5_5_1; 9050 case GL_RGB8_OES: 9051 return GL_UNSIGNED_BYTE; 9052 case GL_RGBA8_OES: 9053 return GL_UNSIGNED_BYTE; 9054 case GL_LUMINANCE8_ALPHA8_EXT: 9055 return GL_UNSIGNED_BYTE; 9056 case GL_LUMINANCE8_EXT: 9057 return GL_UNSIGNED_BYTE; 9058 case GL_ALPHA8_EXT: 9059 return GL_UNSIGNED_BYTE; 9060 case GL_RGBA32F_EXT: 9061 return GL_FLOAT; 9062 case GL_RGB32F_EXT: 9063 return GL_FLOAT; 9064 case GL_ALPHA32F_EXT: 9065 return GL_FLOAT; 9066 case GL_LUMINANCE32F_EXT: 9067 return GL_FLOAT; 9068 case GL_LUMINANCE_ALPHA32F_EXT: 9069 return GL_FLOAT; 9070 case GL_RGBA16F_EXT: 9071 return GL_HALF_FLOAT_OES; 9072 case GL_RGB16F_EXT: 9073 return GL_HALF_FLOAT_OES; 9074 case GL_ALPHA16F_EXT: 9075 return GL_HALF_FLOAT_OES; 9076 case GL_LUMINANCE16F_EXT: 9077 return GL_HALF_FLOAT_OES; 9078 case GL_LUMINANCE_ALPHA16F_EXT: 9079 return GL_HALF_FLOAT_OES; 9080 case GL_BGRA8_EXT: 9081 return GL_UNSIGNED_BYTE; 9082 default: 9083 return GL_NONE; 9084 } 9085} 9086 9087void GLES2DecoderImpl::DoTexStorage2DEXT( 9088 GLenum target, 9089 GLint levels, 9090 GLenum internal_format, 9091 GLsizei width, 9092 GLsizei height) { 9093 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT"); 9094 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) || 9095 TextureManager::ComputeMipMapCount(width, height, 1) < levels) { 9096 SetGLError( 9097 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range"); 9098 return; 9099 } 9100 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 9101 if (!info) { 9102 SetGLError(GL_INVALID_OPERATION, 9103 "glTexStorage2DEXT", "unknown texture for target"); 9104 return; 9105 } 9106 if (info->IsAttachedToFramebuffer()) { 9107 clear_state_dirty_ = true; 9108 } 9109 if (info->IsImmutable()) { 9110 SetGLError(GL_INVALID_OPERATION, 9111 "glTexStorage2DEXT", "texture is immutable"); 9112 return; 9113 } 9114 CopyRealGLErrorsToWrapper(); 9115 glTexStorage2DEXT(target, levels, GetTexInternalFormat(internal_format), 9116 width, height); 9117 GLenum error = PeekGLError(); 9118 if (error == GL_NO_ERROR) { 9119 GLenum format = ExtractFormatFromStorageFormat(internal_format); 9120 GLenum type = ExtractTypeFromStorageFormat(internal_format); 9121 GLsizei level_width = width; 9122 GLsizei level_height = height; 9123 for (int ii = 0; ii < levels; ++ii) { 9124 texture_manager()->SetLevelInfo( 9125 info, target, 0, format, level_width, level_height, 1, 0, format, 9126 type, false); 9127 level_width = std::max(1, level_width >> 1); 9128 level_height = std::max(1, level_height >> 1); 9129 } 9130 info->SetImmutable(true); 9131 } 9132} 9133 9134error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM( 9135 uint32 immediate_data_size, const gles2::GenMailboxCHROMIUM& c) { 9136 MailboxName name; 9137 mailbox_manager()->GenerateMailboxName(&name); 9138 uint32 bucket_id = static_cast<uint32>(c.bucket_id); 9139 Bucket* bucket = CreateBucket(bucket_id); 9140 9141 bucket->SetSize(GL_MAILBOX_SIZE_CHROMIUM); 9142 bucket->SetData(&name, 0, GL_MAILBOX_SIZE_CHROMIUM); 9143 9144 return error::kNoError; 9145} 9146 9147void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target, 9148 const GLbyte* mailbox) { 9149 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 9150 if (!info) { 9151 SetGLError(GL_INVALID_OPERATION, 9152 "glProduceTextureCHROMIUM", "unknown texture for target"); 9153 return; 9154 } 9155 9156 TextureDefinition* definition = texture_manager()->Save(info); 9157 if (!definition) { 9158 SetGLError(GL_INVALID_OPERATION, 9159 "glProduceTextureCHROMIUM", "invalid texture"); 9160 return; 9161 } 9162 9163 if (!group_->mailbox_manager()->ProduceTexture( 9164 target, 9165 *reinterpret_cast<const MailboxName*>(mailbox), 9166 definition, 9167 texture_manager())) { 9168 bool success = texture_manager()->Restore(info, definition); 9169 DCHECK(success); 9170 SetGLError(GL_INVALID_OPERATION, 9171 "glProduceTextureCHROMIUM", "invalid mailbox name"); 9172 return; 9173 } 9174 9175 BindAndApplyTextureParameters(info); 9176} 9177 9178void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target, 9179 const GLbyte* mailbox) { 9180 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); 9181 if (!info) { 9182 SetGLError(GL_INVALID_OPERATION, 9183 "glConsumeTextureCHROMIUM", "unknown texture for target"); 9184 return; 9185 } 9186 9187 scoped_ptr<TextureDefinition> definition( 9188 group_->mailbox_manager()->ConsumeTexture( 9189 target, 9190 *reinterpret_cast<const MailboxName*>(mailbox))); 9191 if (!definition.get()) { 9192 SetGLError(GL_INVALID_OPERATION, 9193 "glConsumeTextureCHROMIUM", "invalid mailbox name"); 9194 return; 9195 } 9196 9197 if (!texture_manager()->Restore(info, definition.release())) { 9198 SetGLError(GL_INVALID_OPERATION, 9199 "glConsumeTextureCHROMIUM", "invalid texture"); 9200 return; 9201 } 9202 9203 BindAndApplyTextureParameters(info); 9204} 9205 9206void GLES2DecoderImpl::DoInsertEventMarkerEXT( 9207 GLsizei length, const GLchar* marker) { 9208 if (!marker) { 9209 marker = ""; 9210 } 9211 debug_marker_manager_.SetMarker( 9212 length ? std::string(marker, length) : std::string(marker)); 9213} 9214 9215void GLES2DecoderImpl::DoPushGroupMarkerEXT( 9216 GLsizei length, const GLchar* marker) { 9217 if (!marker) { 9218 marker = ""; 9219 } 9220 debug_marker_manager_.PushGroup( 9221 length ? std::string(marker, length) : std::string(marker)); 9222} 9223 9224void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) { 9225 debug_marker_manager_.PopGroup(); 9226} 9227 9228void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM( 9229 GLenum target, GLint image_id) { 9230 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM"); 9231 if (target != GL_TEXTURE_2D) { 9232 // This might be supported in the future. 9233 SetGLError( 9234 GL_INVALID_OPERATION, 9235 "glBindTexImage2DCHROMIUM", "requires TEXTURE_2D target"); 9236 return; 9237 } 9238 9239 // Default target might be conceptually valid, but disallow it to avoid 9240 // accidents. 9241 TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault( 9242 target); 9243 if (!info) { 9244 SetGLError(GL_INVALID_OPERATION, 9245 "glBindTexImage2DCHROMIUM", "no texture bound"); 9246 return; 9247 } 9248 9249 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id); 9250 if (!gl_image) { 9251 SetGLError(GL_INVALID_OPERATION, 9252 "glBindTexImage2DCHROMIUM", 9253 "no image found with the given ID"); 9254 return; 9255 } 9256 9257 if (!gl_image->BindTexImage()) { 9258 SetGLError(GL_INVALID_OPERATION, 9259 "glBindTexImage2DCHROMIUM", 9260 "fail to bind image with the given ID"); 9261 return; 9262 } 9263 9264 gfx::Size size = gl_image->GetSize(); 9265 texture_manager()->SetLevelInfo( 9266 info, target, 0, GL_RGBA, size.width(), size.height(), 1, 0, 9267 GL_RGBA, GL_UNSIGNED_BYTE, true); 9268 texture_manager()->SetLevelImage(info, target, 0, gl_image); 9269} 9270 9271void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM( 9272 GLenum target, GLint image_id) { 9273 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM"); 9274 if (target != GL_TEXTURE_2D) { 9275 // This might be supported in the future. 9276 SetGLError( 9277 GL_INVALID_OPERATION, 9278 "glReleaseTexImage2DCHROMIUM", "requires TEXTURE_2D target"); 9279 return; 9280 } 9281 9282 // Default target might be conceptually valid, but disallow it to avoid 9283 // accidents. 9284 TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault( 9285 target); 9286 if (!info) { 9287 SetGLError(GL_INVALID_OPERATION, 9288 "glReleaseTexImage2DCHROMIUM", "no texture bound"); 9289 return; 9290 } 9291 9292 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id); 9293 if (!gl_image) { 9294 SetGLError(GL_INVALID_OPERATION, 9295 "glReleaseTexImage2DCHROMIUM", 9296 "no image found with the given ID"); 9297 return; 9298 } 9299 9300 // Do nothing when image is not currently bound. 9301 if (info->GetLevelImage(target, 0) != gl_image) 9302 return; 9303 9304 gl_image->ReleaseTexImage(); 9305 9306 texture_manager()->SetLevelInfo( 9307 info, target, 0, GL_RGBA, 0, 0, 1, 0, 9308 GL_RGBA, GL_UNSIGNED_BYTE, false); 9309} 9310 9311// Include the auto-generated part of this file. We split this because it means 9312// we can easily edit the non-auto generated parts right here in this file 9313// instead of having to edit some template or the code generator. 9314#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 9315 9316} // namespace gles2 9317} // namespace gpu 9318