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