blob: aab35a482e11f646d61087760c4ec45535e87f53 [file] [log] [blame]
[email protected]529c6672012-01-04 02:18:261// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]96449d2c2009-11-25 00:01:322// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]8a837bb2010-01-05 00:21:245#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
[email protected]74470702010-01-06 18:51:166
7#include <stdio.h>
8
[email protected]1aef98132010-02-23 18:00:079#include <algorithm>
[email protected]f39f4b3f2010-05-12 17:04:0810#include <list>
[email protected]96449d2c2009-11-25 00:01:3211#include <map>
[email protected]94307712012-11-16 23:26:1112#include <stack>
[email protected]f39f4b3f2010-05-12 17:04:0813#include <string>
14#include <vector>
[email protected]5a6db6c2010-04-22 18:32:0615
[email protected]00eb49a2010-08-12 20:46:5716#include "base/at_exit.h"
[email protected]9d37f062011-11-22 01:24:5217#include "base/bind.h"
[email protected]e3c4a9ab2014-03-31 09:07:0218#include "base/callback_helpers.h"
[email protected]e844ae22012-01-14 03:36:2619#include "base/command_line.h"
[email protected]5aa95ac2014-08-14 15:20:5620#include "base/float_util.h"
[email protected]3b63f8f42011-03-28 01:54:1521#include "base/memory/scoped_ptr.h"
[email protected]e3c4a9ab2014-03-31 09:07:0222#include "base/numerics/safe_math.h"
[email protected]f4390962013-06-11 07:29:2223#include "base/strings/string_number_conversions.h"
[email protected]6d668892013-12-04 21:37:1224#include "base/strings/string_split.h"
primiano05dadf012015-01-28 13:10:3225#include "base/trace_event/trace_event.h"
26#include "base/trace_event/trace_event_synthetic_delay.h"
[email protected]d37231fa2010-04-09 21:16:0227#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3228#define GLES2_GPU_SERVICE 1
[email protected]f4390962013-06-11 07:29:2229#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]96449d2c2009-11-25 00:01:3230#include "gpu/command_buffer/common/gles2_cmd_format.h"
31#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]066849e32010-05-03 19:14:1032#include "gpu/command_buffer/common/id_allocator.h"
[email protected]2ad674132013-06-05 07:48:5133#include "gpu/command_buffer/common/mailbox.h"
[email protected]f4390962013-06-11 07:29:2234#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
35#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
[email protected]3916c97e2010-02-25 03:20:5036#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3237#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5038#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2439#include "gpu/command_buffer/service/context_state.h"
[email protected]d3eba342013-04-18 21:11:5040#include "gpu/command_buffer/service/error_state.h"
[email protected]915a59a12010-09-30 21:29:1141#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5842#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3243#include "gpu/command_buffer/service/gl_utils.h"
sievers2384f2b2014-11-18 02:10:3544#include "gpu/command_buffer/service/gles2_cmd_clear_framebuffer.h"
[email protected]43410e92012-04-20 17:06:2845#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4646#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]8f9b8dd2013-09-12 18:05:1347#include "gpu/command_buffer/service/gpu_state_tracer.h"
[email protected]e844ae22012-01-14 03:36:2648#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]fb97b662013-02-20 23:02:1449#include "gpu/command_buffer/service/gpu_tracer.h"
[email protected]09d50362012-10-18 20:54:3750#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5951#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2552#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4753#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5354#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5855#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4756#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4557#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0458#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]a93bb842010-02-16 23:03:4759#include "gpu/command_buffer/service/texture_manager.h"
orglofchcad5a6742014-11-07 19:51:1260#include "gpu/command_buffer/service/valuebuffer_manager.h"
[email protected]944b62f32012-09-27 02:20:4661#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]f4390962013-06-11 07:29:2262#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]6896d7f2014-04-28 20:24:1563#include "third_party/smhasher/src/City.h"
[email protected]5a36dc132013-07-23 23:17:5564#include "ui/gl/gl_fence.h"
[email protected]09d50362012-10-18 20:54:3765#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2766#include "ui/gl/gl_implementation.h"
67#include "ui/gl/gl_surface.h"
[email protected]423e644f2013-06-19 00:48:2768
[email protected]e51bdf32011-11-23 22:21:4669#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:5370#include <IOSurface/IOSurfaceAPI.h>
71// Note that this must be included after gl_bindings.h to avoid conflicts.
72#include <OpenGL/CGLIOSurface.h>
[email protected]e51bdf32011-11-23 22:21:4673#endif
[email protected]de17df392010-04-23 21:09:4174
[email protected]6eb775352013-08-27 05:57:1675#if defined(OS_WIN)
76#include "base/win/win_util.h"
77#endif
78
[email protected]a7a27ace2009-12-12 00:11:2579namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3280namespace gles2 {
81
[email protected]f0d74742011-10-03 16:31:0482namespace {
[email protected]693ca512012-11-13 18:09:1383
[email protected]f0d74742011-10-03 16:31:0484static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]70dc60932013-06-04 03:33:4985static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
[email protected]aff39ac82013-06-08 04:53:1386static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
[email protected]93c2fd82014-04-16 02:46:0687static const char kEXTShaderTextureLodExtension[] = "GL_EXT_shader_texture_lod";
[email protected]693ca512012-11-13 18:09:1388
[email protected]448e459e2013-06-12 17:00:4189static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
90 GLint rangeMax,
91 GLint precision) {
92 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
93}
94
[email protected]8dc1bf92013-03-12 03:58:2195static void GetShaderPrecisionFormatImpl(GLenum shader_type,
96 GLenum precision_type,
97 GLint *range, GLint *precision) {
98 switch (precision_type) {
99 case GL_LOW_INT:
100 case GL_MEDIUM_INT:
101 case GL_HIGH_INT:
102 // These values are for a 32-bit twos-complement integer format.
103 range[0] = 31;
104 range[1] = 30;
105 *precision = 0;
106 break;
107 case GL_LOW_FLOAT:
108 case GL_MEDIUM_FLOAT:
109 case GL_HIGH_FLOAT:
110 // These values are for an IEEE single-precision floating-point format.
111 range[0] = 127;
112 range[1] = 127;
113 *precision = 23;
114 break;
115 default:
116 NOTREACHED();
117 break;
118 }
119
[email protected]8af4d5e2013-03-15 23:55:33120 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
121 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21122 // This function is sometimes defined even though it's really just
123 // a stub, so we need to set range and precision as if it weren't
124 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44125 // On Mac OS with some GPUs, calling this generates a
126 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
127 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21128 glGetShaderPrecisionFormat(shader_type, precision_type,
129 range, precision);
[email protected]448e459e2013-06-12 17:00:41130
131 // TODO(brianderson): Make the following official workarounds.
132
133 // Some drivers have bugs where they report the ranges as a negative number.
134 // Taking the absolute value here shouldn't hurt because negative numbers
135 // aren't expected anyway.
136 range[0] = abs(range[0]);
137 range[1] = abs(range[1]);
138
139 // If the driver reports a precision for highp float that isn't actually
140 // highp, don't pretend like it's supported because shader compilation will
141 // fail anyway.
142 if (precision_type == GL_HIGH_FLOAT &&
143 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
144 range[0] = 0;
145 range[1] = 0;
146 *precision = 0;
147 }
[email protected]8dc1bf92013-03-12 03:58:21148 }
149}
150
[email protected]d286ebbc2014-07-03 17:19:10151static gfx::OverlayTransform GetGFXOverlayTransform(GLenum plane_transform) {
152 switch (plane_transform) {
153 case GL_OVERLAY_TRANSFORM_NONE_CHROMIUM:
154 return gfx::OVERLAY_TRANSFORM_NONE;
155 case GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM:
156 return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
157 case GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM:
158 return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
159 case GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM:
160 return gfx::OVERLAY_TRANSFORM_ROTATE_90;
161 case GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM:
162 return gfx::OVERLAY_TRANSFORM_ROTATE_180;
163 case GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM:
164 return gfx::OVERLAY_TRANSFORM_ROTATE_270;
165 default:
166 return gfx::OVERLAY_TRANSFORM_INVALID;
167 }
168}
169
[email protected]b04e24c2013-01-08 18:35:25170} // namespace
[email protected]f0d74742011-10-03 16:31:04171
[email protected]6217d392010-03-25 22:08:35172class GLES2DecoderImpl;
173
[email protected]ab09b612013-03-11 22:11:51174// Local versions of the SET_GL_ERROR macros
175#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50176 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51177#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50178 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
179 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51180#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50181 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
182 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51183#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50184 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
185 function_name)
[email protected]ab09b612013-03-11 22:11:51186#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50187 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51188#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50189 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51190#define LOCAL_PERFORMANCE_WARNING(msg) \
191 PerformanceWarning(__FILE__, __LINE__, msg)
192#define LOCAL_RENDER_WARNING(msg) \
193 RenderWarning(__FILE__, __LINE__, msg)
194
[email protected]07f54fcc2009-12-22 02:46:30195// Check that certain assumptions the code makes are true. There are places in
196// the code where shared memory is passed direclty to GL. Example, glUniformiv,
197// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
198// a few others) are 32bits. If they are not 32bits the code will have to change
199// to call those GL functions with service side memory and then copy the results
200// to shared memory, converting the sizes.
mostynb7f032092014-12-20 00:36:44201static_assert(sizeof(GLint) == sizeof(uint32), // NOLINT
202 "GLint should be the same size as uint32");
203static_assert(sizeof(GLsizei) == sizeof(uint32), // NOLINT
204 "GLsizei should be the same size as uint32");
205static_assert(sizeof(GLfloat) == sizeof(float), // NOLINT
206 "GLfloat should be the same size as float");
[email protected]07f54fcc2009-12-22 02:46:30207
[email protected]43f28f832010-02-03 02:28:48208// TODO(kbr): the use of this anonymous namespace core dumps the
209// linker on Mac OS X 10.6 when the symbol ordering file is used
210// namespace {
[email protected]96449d2c2009-11-25 00:01:32211
212// Returns the address of the first byte after a struct.
213template <typename T>
214const void* AddressAfterStruct(const T& pod) {
215 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
216}
217
[email protected]07f54fcc2009-12-22 02:46:30218// Returns the address of the frst byte after the struct or NULL if size >
219// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32220template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30221RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
222 uint32 size,
223 uint32 immediate_data_size) {
224 return (size <= immediate_data_size) ?
225 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
226 NULL;
[email protected]96449d2c2009-11-25 00:01:32227}
228
[email protected]07f54fcc2009-12-22 02:46:30229// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18230bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32231 GLuint count,
232 size_t size,
[email protected]a76b0052010-03-05 00:33:18233 unsigned int elements_per_unit,
234 uint32* dst) {
235 uint32 value;
236 if (!SafeMultiplyUint32(count, size, &value)) {
237 return false;
238 }
239 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
240 return false;
241 }
242 *dst = value;
243 return true;
[email protected]96449d2c2009-11-25 00:01:32244}
245
[email protected]258a3313f2011-10-18 20:13:57246// 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
[email protected]6217d392010-03-25 22:08:35277// This class prevents any GL errors that occur when it is in scope from
278// being reported to the client.
279class ScopedGLErrorSuppressor {
280 public:
[email protected]ab09b612013-03-11 22:11:51281 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30282 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35283 ~ScopedGLErrorSuppressor();
284 private:
[email protected]ab09b612013-03-11 22:11:51285 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30286 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35287 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
288};
289
[email protected]2b10c02d2014-01-29 16:43:02290// Temporarily changes a decoder's bound texture and restore it when this
[email protected]6217d392010-03-25 22:08:35291// object goes out of scope. Also temporarily switches to using active texture
292// unit zero in case the client has changed that to something invalid.
[email protected]2b10c02d2014-01-29 16:43:02293class ScopedTextureBinder {
[email protected]6217d392010-03-25 22:08:35294 public:
[email protected]00c2cf92014-03-14 00:08:37295 explicit ScopedTextureBinder(ContextState* state, GLuint id, GLenum target);
[email protected]2b10c02d2014-01-29 16:43:02296 ~ScopedTextureBinder();
[email protected]6217d392010-03-25 22:08:35297
298 private:
[email protected]ce296892013-10-24 22:04:36299 ContextState* state_;
[email protected]2b10c02d2014-01-29 16:43:02300 GLenum target_;
301 DISALLOW_COPY_AND_ASSIGN(ScopedTextureBinder);
[email protected]6217d392010-03-25 22:08:35302};
303
304// Temporarily changes a decoder's bound render buffer and restore it when this
305// object goes out of scope.
306class ScopedRenderBufferBinder {
307 public:
[email protected]00c2cf92014-03-14 00:08:37308 explicit ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35309 ~ScopedRenderBufferBinder();
310
311 private:
[email protected]18e785a2013-10-09 03:29:41312 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35313 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
314};
315
316// Temporarily changes a decoder's bound frame buffer and restore it when this
317// object goes out of scope.
318class ScopedFrameBufferBinder {
319 public:
[email protected]00c2cf92014-03-14 00:08:37320 explicit ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
[email protected]6217d392010-03-25 22:08:35321 ~ScopedFrameBufferBinder();
322
323 private:
324 GLES2DecoderImpl* decoder_;
325 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
326};
327
[email protected]34ff8b0c2010-10-01 20:06:02328// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52329// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27330// if it is bound or enforce_internal_framebuffer is true. If internal is
331// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02332class ScopedResolvedFrameBufferBinder {
333 public:
[email protected]00c2cf92014-03-14 00:08:37334 explicit ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
335 bool enforce_internal_framebuffer,
336 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02337 ~ScopedResolvedFrameBufferBinder();
338
339 private:
340 GLES2DecoderImpl* decoder_;
341 bool resolve_and_bind_;
342 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
343};
344
[email protected]00c2cf92014-03-14 00:08:37345class ScopedModifyPixels {
346 public:
347 explicit ScopedModifyPixels(TextureRef* ref);
348 ~ScopedModifyPixels();
349
350 private:
351 TextureRef* ref_;
352};
353
354ScopedModifyPixels::ScopedModifyPixels(TextureRef* ref) : ref_(ref) {
355 if (ref_)
356 ref_->texture()->OnWillModifyPixels();
357}
358
359ScopedModifyPixels::~ScopedModifyPixels() {
360 if (ref_)
361 ref_->texture()->OnDidModifyPixels();
362}
363
364class ScopedRenderTo {
365 public:
366 explicit ScopedRenderTo(Framebuffer* framebuffer);
367 ~ScopedRenderTo();
368
369 private:
370 const Framebuffer* framebuffer_;
371};
372
373ScopedRenderTo::ScopedRenderTo(Framebuffer* framebuffer)
374 : framebuffer_(framebuffer) {
375 if (framebuffer)
376 framebuffer_->OnWillRenderTo();
377}
378
379ScopedRenderTo::~ScopedRenderTo() {
380 if (framebuffer_)
381 framebuffer_->OnDidRenderTo();
382}
383
[email protected]6217d392010-03-25 22:08:35384// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35385class BackTexture {
[email protected]6217d392010-03-25 22:08:35386 public:
[email protected]ce296892013-10-24 22:04:36387 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35388 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35389
390 // Create a new render texture.
391 void Create();
392
393 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09394 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35395
396 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58397 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35398
399 // Destroy the render texture. This must be explicitly called before
400 // destroying this object.
401 void Destroy();
402
[email protected]97872062010-11-03 19:07:05403 // Invalidate the texture. This can be used when a context is lost and it is
404 // not possible to make it current in order to free the resource.
405 void Invalidate();
406
[email protected]6217d392010-03-25 22:08:35407 GLuint id() const {
408 return id_;
409 }
410
[email protected]d37231fa2010-04-09 21:16:02411 gfx::Size size() const {
412 return size_;
413 }
414
[email protected]6217d392010-03-25 22:08:35415 private:
[email protected]ff6493f2012-07-31 19:52:25416 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36417 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48418 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35419 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02420 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35421 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35422};
423
424// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35425class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35426 public:
[email protected]d5a28e452013-10-10 01:01:40427 explicit BackRenderbuffer(
428 RenderbufferManager* renderbuffer_manager,
429 MemoryTracker* memory_tracker,
430 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35431 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35432
433 // Create a new render buffer.
434 void Create();
435
436 // Set the initial size and format of a render buffer or resize it.
[email protected]f42f05b2013-11-15 21:46:18437 bool AllocateStorage(const FeatureInfo* feature_info,
438 const gfx::Size& size,
439 GLenum format,
440 GLsizei samples);
[email protected]6217d392010-03-25 22:08:35441
442 // Destroy the render buffer. This must be explicitly called before destroying
443 // this object.
444 void Destroy();
445
[email protected]97872062010-11-03 19:07:05446 // Invalidate the render buffer. This can be used when a context is lost and
447 // it is not possible to make it current in order to free the resource.
448 void Invalidate();
449
[email protected]6217d392010-03-25 22:08:35450 GLuint id() const {
451 return id_;
452 }
453
454 private:
[email protected]d5a28e452013-10-10 01:01:40455 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25456 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40457 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48458 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35459 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35460 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35461};
462
463// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35464class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35465 public:
[email protected]ed9f9cd2013-02-27 21:12:35466 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
467 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35468
469 // Create a new frame buffer.
470 void Create();
471
472 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35473 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35474
[email protected]b9363b22010-06-09 22:06:15475 // Attach a render buffer to a frame buffer. Note that this unbinds any
476 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35477 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35478
[email protected]6217d392010-03-25 22:08:35479 // Destroy the frame buffer. This must be explicitly called before destroying
480 // this object.
481 void Destroy();
482
[email protected]97872062010-11-03 19:07:05483 // Invalidate the frame buffer. This can be used when a context is lost and it
484 // is not possible to make it current in order to free the resource.
485 void Invalidate();
486
[email protected]6217d392010-03-25 22:08:35487 // See glCheckFramebufferStatusEXT.
488 GLenum CheckStatus();
489
490 GLuint id() const {
491 return id_;
492 }
493
494 private:
495 GLES2DecoderImpl* decoder_;
496 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35497 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35498};
[email protected]34ff8b0c2010-10-01 20:06:02499
[email protected]5a36dc132013-07-23 23:17:55500struct FenceCallback {
501 explicit FenceCallback()
502 : fence(gfx::GLFence::Create()) {
503 DCHECK(fence);
504 }
[email protected]5a36dc132013-07-23 23:17:55505 std::vector<base::Closure> callbacks;
506 scoped_ptr<gfx::GLFence> fence;
507};
508
[email protected]e3c4a9ab2014-03-31 09:07:02509class AsyncUploadTokenCompletionObserver
510 : public AsyncPixelTransferCompletionObserver {
511 public:
512 explicit AsyncUploadTokenCompletionObserver(uint32 async_upload_token)
513 : async_upload_token_(async_upload_token) {
514 }
515
dcheng1f4d1d72014-10-21 16:21:58516 void DidComplete(const AsyncMemoryParams& mem_params) override {
dcheng6ef3c5552014-08-30 05:34:19517 DCHECK(mem_params.buffer().get());
[email protected]e3c4a9ab2014-03-31 09:07:02518 void* data = mem_params.GetDataAddress();
519 AsyncUploadSync* sync = static_cast<AsyncUploadSync*>(data);
520 sync->SetAsyncUploadToken(async_upload_token_);
521 }
522
523 private:
dcheng1f4d1d72014-10-21 16:21:58524 ~AsyncUploadTokenCompletionObserver() override {}
[email protected]e3c4a9ab2014-03-31 09:07:02525
526 uint32 async_upload_token_;
527
528 DISALLOW_COPY_AND_ASSIGN(AsyncUploadTokenCompletionObserver);
529};
530
[email protected]43f28f832010-02-03 02:28:48531// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32532
[email protected]efc87712014-07-09 00:22:47533// static
534const unsigned int GLES2Decoder::kDefaultStencilMask =
535 static_cast<unsigned int>(-1);
536
[email protected]ddb1e5a2010-12-13 20:10:45537bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
538 uint32* service_texture_id) {
539 return false;
540}
541
[email protected]a3ded6d2010-10-19 06:44:39542GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06543 : initialized_(false),
544 debug_(false),
zmo84c08202014-11-23 15:28:40545 log_commands_(false),
546 unsafe_es3_apis_enabled_(false) {
[email protected]96449d2c2009-11-25 00:01:32547}
548
[email protected]3916c97e2010-02-25 03:20:50549GLES2Decoder::~GLES2Decoder() {
550}
551
[email protected]cac16542014-01-15 17:53:51552void GLES2Decoder::BeginDecoding() {}
553
554void GLES2Decoder::EndDecoding() {}
555
[email protected]f39f4b3f2010-05-12 17:04:08556// This class implements GLES2Decoder so we don't have to expose all the GLES2
557// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54558class GLES2DecoderImpl : public GLES2Decoder,
[email protected]828a3932014-04-02 14:43:13559 public FramebufferManager::TextureDetachObserver,
560 public ErrorStateClient {
[email protected]f39f4b3f2010-05-12 17:04:08561 public:
[email protected]aa7666122011-09-02 19:45:52562 explicit GLES2DecoderImpl(ContextGroup* group);
dcheng1f4d1d72014-10-21 16:21:58563 ~GLES2DecoderImpl() override;
[email protected]f39f4b3f2010-05-12 17:04:08564
[email protected]96449d2c2009-11-25 00:01:32565 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58566 Error DoCommand(unsigned int command,
567 unsigned int arg_count,
568 const void* args) override;
[email protected]96449d2c2009-11-25 00:01:32569
dcheng1f4d1d72014-10-21 16:21:58570 error::Error DoCommands(unsigned int num_commands,
571 const void* buffer,
572 int num_entries,
573 int* entries_processed) override;
vmiura8266ca72014-09-09 21:37:00574
vmiura1c2b1de2014-09-19 19:03:24575 template <bool DebugImpl>
576 error::Error DoCommandsImpl(unsigned int num_commands,
577 const void* buffer,
578 int num_entries,
579 int* entries_processed);
580
[email protected]96449d2c2009-11-25 00:01:32581 // Overridden from AsyncAPIInterface.
dcheng1f4d1d72014-10-21 16:21:58582 const char* GetCommandName(unsigned int command_id) const override;
[email protected]96449d2c2009-11-25 00:01:32583
584 // Overridden from GLES2Decoder.
dcheng1f4d1d72014-10-21 16:21:58585 bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
586 const scoped_refptr<gfx::GLContext>& context,
587 bool offscreen,
588 const gfx::Size& size,
589 const DisallowedFeatures& disallowed_features,
590 const std::vector<int32>& attribs) override;
591 void Destroy(bool have_context) override;
592 void SetSurface(const scoped_refptr<gfx::GLSurface>& surface) override;
593 void ProduceFrontBuffer(const Mailbox& mailbox) override;
594 bool ResizeOffscreenFrameBuffer(const gfx::Size& size) override;
[email protected]9a5afa432011-07-22 18:16:39595 void UpdateParentTextureInfo();
dcheng1f4d1d72014-10-21 16:21:58596 bool MakeCurrent() override;
597 GLES2Util* GetGLES2Util() override { return &util_; }
598 gfx::GLContext* GetGLContext() override { return context_.get(); }
599 ContextGroup* GetContextGroup() override { return group_.get(); }
600 Capabilities GetCapabilities() override;
601 void RestoreState(const ContextState* prev_state) override;
[email protected]29a4d902013-02-26 20:18:06602
dcheng1f4d1d72014-10-21 16:21:58603 void RestoreActiveTexture() const override { state_.RestoreActiveTexture(); }
604 void RestoreAllTextureUnitBindings(
mohan.reddy5e1b8952014-10-08 01:38:17605 const ContextState* prev_state) const override {
[email protected]5baa86bc2014-01-16 04:33:16606 state_.RestoreAllTextureUnitBindings(prev_state);
[email protected]217004512013-05-10 21:25:55607 }
dcheng1f4d1d72014-10-21 16:21:58608 void RestoreActiveTextureUnitBinding(unsigned int target) const override {
[email protected]4b2d2b262014-03-21 22:05:27609 state_.RestoreActiveTextureUnitBinding(target);
610 }
dcheng1f4d1d72014-10-21 16:21:58611 void RestoreBufferBindings() const override {
[email protected]29a4d902013-02-26 20:18:06612 state_.RestoreBufferBindings();
613 }
dcheng1f4d1d72014-10-21 16:21:58614 void RestoreGlobalState() const override { state_.RestoreGlobalState(NULL); }
615 void RestoreProgramBindings() const override {
[email protected]29a4d902013-02-26 20:18:06616 state_.RestoreProgramBindings();
617 }
dcheng1f4d1d72014-10-21 16:21:58618 void RestoreTextureUnitBindings(unsigned unit) const override {
[email protected]5baa86bc2014-01-16 04:33:16619 state_.RestoreTextureUnitBindings(unit, NULL);
[email protected]29a4d902013-02-26 20:18:06620 }
dcheng1f4d1d72014-10-21 16:21:58621 void RestoreFramebufferBindings() const override;
622 void RestoreRenderbufferBindings() override;
623 void RestoreTextureState(unsigned service_id) const override;
[email protected]29a4d902013-02-26 20:18:06624
dcheng1f4d1d72014-10-21 16:21:58625 void ClearAllAttributes() const override;
626 void RestoreAllAttributes() const override;
[email protected]cd2ef752014-02-12 23:16:03627
dcheng1f4d1d72014-10-21 16:21:58628 QueryManager* GetQueryManager() override { return query_manager_.get(); }
629 VertexArrayManager* GetVertexArrayManager() override {
[email protected]944b62f32012-09-27 02:20:46630 return vertex_array_manager_.get();
631 }
dcheng1f4d1d72014-10-21 16:21:58632 ImageManager* GetImageManager() override { return image_manager_.get(); }
orglofch33edd842014-12-03 05:32:15633
634 ValuebufferManager* GetValuebufferManager() override {
635 return valuebuffer_manager();
636 }
637
revemancc241eb2014-11-11 03:30:37638 bool ProcessPendingQueries(bool did_finish) override;
orglofch33edd842014-12-03 05:32:15639
dcheng1f4d1d72014-10-21 16:21:58640 bool HasMoreIdleWork() override;
641 void PerformIdleWork() override;
[email protected]43f28f832010-02-03 02:28:48642
dcheng1f4d1d72014-10-21 16:21:58643 void WaitForReadPixels(base::Closure callback) override;
[email protected]5a36dc132013-07-23 23:17:55644
dcheng1f4d1d72014-10-21 16:21:58645 void SetResizeCallback(
mohan.reddy5e1b8952014-10-08 01:38:17646 const base::Callback<void(gfx::Size, float)>& callback) override;
[email protected]22f320a2011-08-30 01:17:00647
dcheng1f4d1d72014-10-21 16:21:58648 Logger* GetLogger() override;
[email protected]cac16542014-01-15 17:53:51649
dcheng1f4d1d72014-10-21 16:21:58650 void BeginDecoding() override;
651 void EndDecoding() override;
[email protected]cac16542014-01-15 17:53:51652
dcheng1f4d1d72014-10-21 16:21:58653 ErrorState* GetErrorState() override;
654 const ContextState* GetContextState() override { return &state_; }
[email protected]1d82e822013-04-10 21:32:32655
dcheng1f4d1d72014-10-21 16:21:58656 void SetShaderCacheCallback(const ShaderCacheCallback& callback) override;
657 void SetWaitSyncPointCallback(const WaitSyncPointCallback& callback) override;
[email protected]22f320a2011-08-30 01:17:00658
dcheng1f4d1d72014-10-21 16:21:58659 AsyncPixelTransferManager* GetAsyncPixelTransferManager() override;
660 void ResetAsyncPixelTransferManagerForTest() override;
661 void SetAsyncPixelTransferManagerForTest(
mohan.reddy5e1b8952014-10-08 01:38:17662 AsyncPixelTransferManager* manager) override;
dcheng1f4d1d72014-10-21 16:21:58663 void SetIgnoreCachedStateForTest(bool ignore) override;
[email protected]69a8701e2013-03-07 21:31:09664 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59665
dcheng1f4d1d72014-10-21 16:21:58666 bool GetServiceTextureId(uint32 client_texture_id,
667 uint32* service_texture_id) override;
[email protected]43f28f832010-02-03 02:28:48668
dcheng1f4d1d72014-10-21 16:21:58669 uint32 GetTextureUploadCount() override;
670 base::TimeDelta GetTotalTextureUploadTime() override;
671 base::TimeDelta GetTotalProcessingCommandsTime() override;
672 void AddProcessingCommandsTime(base::TimeDelta) override;
[email protected]63b465922012-09-06 02:04:52673
[email protected]8e3e0662010-08-23 18:46:30674 // Restores the current state to the user's settings.
675 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30676
[email protected]297ca1c2011-06-20 23:08:46677 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
678 void ApplyDirtyState();
679
680 // These check the state of the currently bound framebuffer or the
681 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54682 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
683 // check with all attached and enabled color attachments.
684 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46685 bool BoundFramebufferHasDepthAttachment();
686 bool BoundFramebufferHasStencilAttachment();
687
dcheng1f4d1d72014-10-21 16:21:58688 error::ContextLostReason GetContextLostReason() override;
[email protected]38d139d2011-07-14 00:38:43689
[email protected]91c94eb2013-10-22 10:32:54690 // Overridden from FramebufferManager::TextureDetachObserver:
dcheng1f4d1d72014-10-21 16:21:58691 void OnTextureRefDetachedFromFramebuffer(TextureRef* texture) override;
[email protected]91c94eb2013-10-22 10:32:54692
[email protected]828a3932014-04-02 14:43:13693 // Overriden from ErrorStateClient.
oetuaho37cc50e2014-10-31 11:19:20694 void OnContextLostError() override;
dcheng1f4d1d72014-10-21 16:21:58695 void OnOutOfMemoryError() override;
[email protected]828a3932014-04-02 14:43:13696
[email protected]8875a5f2014-06-27 08:33:47697 // Ensure Renderbuffer corresponding to last DoBindRenderbuffer() is bound.
698 void EnsureRenderbufferBound();
699
[email protected]f42f05b2013-11-15 21:46:18700 // Helpers to facilitate calling into compatible extensions.
701 static void RenderbufferStorageMultisampleHelper(
702 const FeatureInfo* feature_info,
703 GLenum target,
704 GLsizei samples,
705 GLenum internal_format,
706 GLsizei width,
707 GLsizei height);
708
709 void BlitFramebufferHelper(GLint srcX0,
710 GLint srcY0,
711 GLint srcX1,
712 GLint srcY1,
713 GLint dstX0,
714 GLint dstY0,
715 GLint dstX1,
716 GLint dstY1,
717 GLbitfield mask,
718 GLenum filter);
[email protected]345ba902013-11-14 21:39:00719
[email protected]96449d2c2009-11-25 00:01:32720 private:
[email protected]70d34263c2013-01-09 00:27:45721 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02722 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35723 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35724
[email protected]c2f8c8402010-12-06 18:07:24725 // Initialize or re-initialize the shader translator.
726 bool InitializeShaderTranslator();
727
[email protected]302ce6d2011-07-07 23:28:11728 void UpdateCapabilities();
729
[email protected]ae51d192010-04-27 00:48:03730 // Helpers for the glGen and glDelete functions.
731 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
732 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
733 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
734 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
735 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
736 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
737 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
738 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
orglofchcad5a6742014-11-07 19:51:12739 bool GenValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
740 void DeleteValuebuffersCHROMIUMHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53741 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
742 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46743 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
744 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47745
[email protected]e3c4a9ab2014-03-31 09:07:02746 // Helper for async upload token completion notification callback.
747 base::Closure AsyncUploadTokenCompletionClosure(uint32 async_upload_token,
748 uint32 sync_data_shm_id,
749 uint32 sync_data_shm_offset);
750
751
752
[email protected]70d34263c2013-01-09 00:27:45753 // Workarounds
754 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51755 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45756
[email protected]3916c97e2010-02-25 03:20:50757 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50758 BufferManager* buffer_manager() {
759 return group_->buffer_manager();
760 }
761
[email protected]a25fa872010-03-25 02:57:58762 RenderbufferManager* renderbuffer_manager() {
763 return group_->renderbuffer_manager();
764 }
765
766 FramebufferManager* framebuffer_manager() {
767 return group_->framebuffer_manager();
768 }
769
orglofchcad5a6742014-11-07 19:51:12770 ValuebufferManager* valuebuffer_manager() {
771 return group_->valuebuffer_manager();
772 }
773
[email protected]3916c97e2010-02-25 03:20:50774 ProgramManager* program_manager() {
775 return group_->program_manager();
776 }
777
778 ShaderManager* shader_manager() {
779 return group_->shader_manager();
780 }
781
[email protected]03cef9b2014-04-03 15:58:14782 ShaderTranslatorCache* shader_translator_cache() {
783 return group_->shader_translator_cache();
784 }
785
[email protected]29a4d902013-02-26 20:18:06786 const TextureManager* texture_manager() const {
787 return group_->texture_manager();
788 }
789
[email protected]3916c97e2010-02-25 03:20:50790 TextureManager* texture_manager() {
791 return group_->texture_manager();
792 }
793
[email protected]78b514b2012-05-01 21:50:59794 MailboxManager* mailbox_manager() {
795 return group_->mailbox_manager();
796 }
797
[email protected]b63f1d62014-07-18 15:40:59798 ImageManager* image_manager() { return image_manager_.get(); }
[email protected]09d50362012-10-18 20:54:37799
[email protected]944b62f32012-09-27 02:20:46800 VertexArrayManager* vertex_array_manager() {
801 return vertex_array_manager_.get();
802 }
803
[email protected]7989c9e2013-01-23 06:39:26804 MemoryTracker* memory_tracker() {
805 return group_->memory_tracker();
806 }
807
808 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
809 MemoryTracker* tracker = memory_tracker();
810 if (tracker) {
811 return tracker->EnsureGPUMemoryAvailable(estimated_size);
812 }
813 return true;
814 }
815
[email protected]34ff8b0c2010-10-01 20:06:02816 bool IsOffscreenBufferMultisampled() const {
817 return offscreen_target_samples_ > 1;
818 }
819
[email protected]ed9f9cd2013-02-27 21:12:35820 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49821 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03822 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35823 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47824 }
825
826 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49827 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07828 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47829 }
830
831 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35832 void RemoveTexture(GLuint client_id) {
833 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50834 }
[email protected]a93bb842010-02-16 23:03:47835
[email protected]d37231fa2010-04-09 21:16:02836 // Get the size (in pixels) of the currently bound frame buffer (either FBO
837 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30838 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02839
[email protected]9edc6b22010-12-23 02:00:26840 // Get the format of the currently bound frame buffer (either FBO or regular
841 // back buffer)
[email protected]68586372013-12-11 01:27:59842 GLenum GetBoundReadFrameBufferTextureType();
[email protected]9edc6b22010-12-23 02:00:26843 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46844 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26845
[email protected]a93bb842010-02-16 23:03:47846 // Wrapper for CompressedTexImage2D commands.
847 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37848 GLenum target,
849 GLint level,
850 GLenum internal_format,
851 GLsizei width,
852 GLsizei height,
853 GLint border,
854 GLsizei image_size,
855 const void* data);
[email protected]a93bb842010-02-16 23:03:47856
[email protected]cadde4a2010-07-31 17:10:43857 // Wrapper for CompressedTexSubImage2D.
858 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37859 GLenum target,
860 GLint level,
861 GLint xoffset,
862 GLint yoffset,
863 GLsizei width,
864 GLsizei height,
865 GLenum format,
866 GLsizei imageSize,
867 const void * data);
[email protected]cadde4a2010-07-31 17:10:43868
869 // Wrapper for CopyTexImage2D.
870 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37871 GLenum target,
872 GLint level,
873 GLenum internal_format,
874 GLint x,
875 GLint y,
876 GLsizei width,
877 GLsizei height,
878 GLint border);
[email protected]cadde4a2010-07-31 17:10:43879
[email protected]6d792ee12013-05-15 00:40:56880 // Wrapper for SwapBuffers.
881 void DoSwapBuffers();
882
bajones2345c1f2014-12-09 04:45:51883 // Wrapper for SwapInterval.
884 void DoSwapInterval(int interval);
885
[email protected]cadde4a2010-07-31 17:10:43886 // Wrapper for CopyTexSubImage2D.
887 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37888 GLenum target,
889 GLint level,
890 GLint xoffset,
891 GLint yoffset,
892 GLint x,
893 GLint y,
894 GLsizei width,
895 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43896
[email protected]f598f422012-12-07 08:30:03897 // Validation for TexSubImage2D.
898 bool ValidateTexSubImage2D(
899 error::Error* error,
900 const char* function_name,
901 GLenum target,
902 GLint level,
903 GLint xoffset,
904 GLint yoffset,
905 GLsizei width,
906 GLsizei height,
907 GLenum format,
908 GLenum type,
909 const void * data);
910
[email protected]cadde4a2010-07-31 17:10:43911 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03912 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37913 GLenum target,
914 GLint level,
915 GLint xoffset,
916 GLint yoffset,
917 GLsizei width,
918 GLsizei height,
919 GLenum format,
920 GLenum type,
921 const void * data);
[email protected]cadde4a2010-07-31 17:10:43922
[email protected]32145a92012-12-17 09:01:59923 // Extra validation for async tex(Sub)Image2D.
924 bool ValidateAsyncTransfer(
925 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47926 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59927 GLenum target,
928 GLint level,
929 const void * data);
930
[email protected]e51bdf32011-11-23 22:21:46931 // Wrapper for TexImageIOSurface2DCHROMIUM.
932 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37933 GLenum target,
934 GLsizei width,
935 GLsizei height,
936 GLuint io_surface_id,
937 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46938
[email protected]43410e92012-04-20 17:06:28939 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37940 GLenum target,
941 GLuint source_id,
942 GLuint target_id,
943 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54944 GLenum internal_format,
945 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28946
[email protected]97dc7cbe2011-12-06 17:26:17947 // Wrapper for TexStorage2DEXT.
948 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37949 GLenum target,
950 GLint levels,
951 GLenum internal_format,
952 GLsizei width,
953 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17954
[email protected]78b514b2012-05-01 21:50:59955 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22956 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target,
957 const GLbyte* key);
958 void ProduceTextureRef(std::string func_name, TextureRef* texture_ref,
959 GLenum target, const GLbyte* data);
960
[email protected]78b514b2012-05-01 21:50:59961 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
[email protected]43f253da2014-06-10 17:51:22962 void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key,
963 GLuint client_id);
[email protected]78b514b2012-05-01 21:50:59964
orglofchcad5a6742014-11-07 19:51:12965 bool DoIsValuebufferCHROMIUM(GLuint client_id);
966 void DoBindValueBufferCHROMIUM(GLenum target, GLuint valuebuffer);
967 void DoSubscribeValueCHROMIUM(GLenum target, GLenum subscription);
968 void DoPopulateSubscribedValuesCHROMIUM(GLenum target);
969 void DoUniformValueBufferCHROMIUM(GLint location,
970 GLenum target,
971 GLenum subscription);
972
[email protected]09d50362012-10-18 20:54:37973 void DoBindTexImage2DCHROMIUM(
974 GLenum target,
975 GLint image_id);
976 void DoReleaseTexImage2DCHROMIUM(
977 GLenum target,
978 GLint image_id);
979
[email protected]94307712012-11-16 23:26:11980 void DoTraceEndCHROMIUM(void);
981
[email protected]2f143d482013-03-14 18:04:49982 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
983
[email protected]a6a09f852014-05-23 13:05:03984 void DoLoseContextCHROMIUM(GLenum current, GLenum other);
985
kkinnunen337d59632014-08-26 10:19:57986 void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix);
987 void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode);
988
[email protected]ed9f9cd2013-02-27 21:12:35989 // Creates a Program for the given program.
990 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57991 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35992 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47993 }
994
[email protected]07f54fcc2009-12-22 02:46:30995 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35996 Program* GetProgram(GLuint client_id) {
997 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46998 }
[email protected]07f54fcc2009-12-22 02:46:30999
[email protected]cae20172012-12-07 00:06:191000#if defined(NDEBUG)
1001 void LogClientServiceMapping(
1002 const char* /* function_name */,
1003 GLuint /* client_id */,
1004 GLuint /* service_id */) {
1005 }
1006 template<typename T>
1007 void LogClientServiceForInfo(
1008 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
1009 }
1010#else
1011 void LogClientServiceMapping(
1012 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:261013 if (service_logging_) {
[email protected]65f7efe2013-11-28 03:11:471014 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
1015 << ": client_id = " << client_id
1016 << ", service_id = " << service_id;
[email protected]2a22fe72012-12-07 04:21:261017 }
[email protected]cae20172012-12-07 00:06:191018 }
1019 template<typename T>
1020 void LogClientServiceForInfo(
1021 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:261022 if (info) {
[email protected]cae20172012-12-07 00:06:191023 LogClientServiceMapping(function_name, client_id, info->service_id());
1024 }
1025 }
1026#endif
1027
[email protected]6b8cf1a2010-05-06 16:13:581028 // Gets the program info for the given program. If it's not a program
1029 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:351030 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:581031 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421032 Program* program = GetProgram(client_id);
1033 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:351034 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:511035 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431036 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:581037 } else {
[email protected]ab09b612013-03-11 22:11:511038 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:581039 }
1040 }
[email protected]df37b9932013-03-08 05:21:421041 LogClientServiceForInfo(program, client_id, function_name);
1042 return program;
[email protected]6b8cf1a2010-05-06 16:13:581043 }
1044
1045
[email protected]ed9f9cd2013-02-27 21:12:351046 // Creates a Shader for the given shader.
1047 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:571048 GLuint client_id,
1049 GLuint service_id,
1050 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:351051 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:571052 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:311053 }
1054
1055 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351056 Shader* GetShader(GLuint client_id) {
1057 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:311058 }
1059
[email protected]6b8cf1a2010-05-06 16:13:581060 // Gets the shader info for the given shader. If it's not a shader generates a
1061 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:351062 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:581063 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421064 Shader* shader = GetShader(client_id);
1065 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:351066 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:511067 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431068 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:581069 } else {
[email protected]ab09b612013-03-11 22:11:511070 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431071 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:581072 }
1073 }
[email protected]df37b9932013-03-08 05:21:421074 LogClientServiceForInfo(shader, client_id, function_name);
1075 return shader;
[email protected]6b8cf1a2010-05-06 16:13:581076 }
1077
[email protected]a93bb842010-02-16 23:03:471078 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:351079 void CreateBuffer(GLuint client_id, GLuint service_id) {
1080 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471081 }
1082
[email protected]07f54fcc2009-12-22 02:46:301083 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:211084 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:071085 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1086 return buffer;
[email protected]1d32bc82010-01-13 22:06:461087 }
[email protected]07f54fcc2009-12-22 02:46:301088
[email protected]a93bb842010-02-16 23:03:471089 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1090 // on glDeleteBuffers so we can make sure the user does not try to render
1091 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351092 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471093
[email protected]a25fa872010-03-25 02:57:581094 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351095 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1096 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581097 }
1098
1099 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061100 Framebuffer* GetFramebuffer(GLuint client_id) {
1101 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581102 }
1103
1104 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351105 void RemoveFramebuffer(GLuint client_id) {
1106 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581107 }
1108
1109 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351110 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1111 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031112 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581113 }
1114
1115 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271116 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1117 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581118 }
1119
1120 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351121 void RemoveRenderbuffer(GLuint client_id) {
1122 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581123 }
1124
orglofchcad5a6742014-11-07 19:51:121125 // Creates a valuebuffer info for the given valuebuffer.
1126 void CreateValuebuffer(GLuint client_id) {
1127 return valuebuffer_manager()->CreateValuebuffer(client_id);
1128 }
1129
1130 // Gets the valuebuffer info for a given valuebuffer.
1131 Valuebuffer* GetValuebuffer(GLuint client_id) {
1132 return valuebuffer_manager()->GetValuebuffer(client_id);
1133 }
1134
1135 // Removes the valuebuffer info for the given valuebuffer.
1136 void RemoveValuebuffer(GLuint client_id) {
1137 valuebuffer_manager()->RemoveValuebuffer(client_id);
1138 }
1139
[email protected]944b62f32012-09-27 02:20:461140 // Gets the vertex attrib manager for the given vertex array.
1141 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1142 VertexAttribManager* info =
1143 vertex_array_manager()->GetVertexAttribManager(client_id);
1144 return info;
1145 }
1146
1147 // Removes the vertex attrib manager for the given vertex array.
1148 void RemoveVertexAttribManager(GLuint client_id) {
1149 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1150 }
1151
1152 // Creates a vertex attrib manager for the given vertex array.
[email protected]da364812014-05-09 21:39:481153 scoped_refptr<VertexAttribManager> CreateVertexAttribManager(
1154 GLuint client_id,
1155 GLuint service_id,
1156 bool client_visible) {
1157 return vertex_array_manager()->CreateVertexAttribManager(
1158 client_id, service_id, group_->max_vertex_attribs(), client_visible);
[email protected]944b62f32012-09-27 02:20:461159 }
1160
[email protected]258a3313f2011-10-18 20:13:571161 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331162 void DoBindUniformLocationCHROMIUM(
1163 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571164
[email protected]558847a2010-03-24 07:02:541165 error::Error GetAttribLocationHelper(
zmo4a16ff992015-02-05 22:18:411166 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1167 const std::string& name_str);
[email protected]558847a2010-03-24 07:02:541168
1169 error::Error GetUniformLocationHelper(
zmo4a16ff992015-02-05 22:18:411170 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1171 const std::string& name_str);
[email protected]558847a2010-03-24 07:02:541172
zmo5393fb52015-01-27 01:50:481173 error::Error GetFragDataLocationHelper(
zmo4a16ff992015-02-05 22:18:411174 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1175 const std::string& name_str);
zmo5393fb52015-01-27 01:50:481176
zmo1bb3d1d2015-01-21 20:29:431177 // Wrapper for glShaderSource.
1178 void DoShaderSource(
1179 GLuint client_id, GLsizei count, const char** data, const GLint* length);
[email protected]07f54fcc2009-12-22 02:46:301180
zmo38923562015-01-29 20:17:391181 // Wrapper for glTransformFeedbackVaryings.
1182 void DoTransformFeedbackVaryings(
1183 GLuint client_program_id, GLsizei count, const char* const* varyings,
1184 GLenum buffer_mode);
1185
[email protected]0d6bfdc2011-11-02 01:32:201186 // Clear any textures used by the current program.
1187 bool ClearUnclearedTextures();
1188
[email protected]0d6bfdc2011-11-02 01:32:201189 // Clears any uncleared attachments attached to the given frame buffer.
1190 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061191 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281192
[email protected]0d6bfdc2011-11-02 01:32:201193 // overridden from GLES2Decoder
dcheng1f4d1d72014-10-21 16:21:581194 bool ClearLevel(unsigned service_id,
1195 unsigned bind_target,
1196 unsigned target,
1197 int level,
1198 unsigned internal_format,
1199 unsigned format,
1200 unsigned type,
1201 int width,
1202 int height,
1203 bool is_texture_immutable) override;
[email protected]0d6bfdc2011-11-02 01:32:201204
[email protected]c007aa02010-09-02 22:22:401205 // Restore all GL state that affects clearing.
1206 void RestoreClearState();
1207
[email protected]3a2e7c7b2010-08-06 01:12:281208 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461209 // Returns: true if glEnable/glDisable should actually be called.
1210 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281211
[email protected]0d6bfdc2011-11-02 01:32:201212 // Check that the currently bound framebuffers are valid.
1213 // Generates GL error if not.
1214 bool CheckBoundFramebuffersValid(const char* func_name);
1215
[email protected]2ea5950d2014-07-09 18:20:341216 // Check that the currently bound read framebuffer has a color image
1217 // attached. Generates GL error if not.
1218 bool CheckBoundReadFramebufferColorAttachment(const char* func_name);
1219
zmo383512cf2014-10-14 00:11:001220 // Check that the currently bound read framebuffer's color image
1221 // isn't the target texture of the glCopyTex{Sub}Image2D.
1222 bool FormsTextureCopyingFeedbackLoop(TextureRef* texture, GLint level);
1223
[email protected]0d6bfdc2011-11-02 01:32:201224 // Check if a framebuffer meets our requirements.
1225 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351226 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201227 GLenum target,
1228 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271229
orglofchcad5a6742014-11-07 19:51:121230 // Check if the current valuebuffer exists and is valid. If not generates
1231 // the appropriate GL error. Returns true if the current valuebuffer is in
1232 // a usable state.
1233 bool CheckCurrentValuebuffer(const char* function_name);
1234
1235 // Check if the current valuebuffer exists and is valiud and that the
1236 // value buffer is actually subscribed to the given subscription
1237 bool CheckCurrentValuebufferForSubscription(GLenum subscription,
1238 const char* function_name);
1239
1240 // Check if the location can be used for the given subscription target. If not
1241 // generates the appropriate GL error. Returns true if the location is usable
1242 bool CheckSubscriptionTarget(GLint location,
1243 GLenum subscription,
1244 const char* function_name);
1245
[email protected]939e7362010-05-13 20:49:101246 // Checks if the current program exists and is valid. If not generates the
1247 // appropriate GL error. Returns true if the current program is in a usable
1248 // state.
1249 bool CheckCurrentProgram(const char* function_name);
1250
1251 // Checks if the current program exists and is valid and that location is not
1252 // -1. If the current program is not valid generates the appropriate GL
1253 // error. Returns true if the current program is in a usable state and
1254 // location is not -1.
1255 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1256
zmof9a81360f2014-10-17 00:06:141257 // Checks if the current program samples a texture that is also the color
1258 // image of the current bound framebuffer, i.e., the source and destination
1259 // of the draw operation are the same.
1260 bool CheckDrawingFeedbackLoops();
1261
orglofchcad5a6742014-11-07 19:51:121262 // Checks if |api_type| is valid for the given uniform
1263 // If the api type is not valid generates the appropriate GL
1264 // error. Returns true if |api_type| is valid for the uniform
1265 bool CheckUniformForApiType(const Program::UniformInfo* info,
1266 const char* function_name,
1267 Program::UniformApiType api_type);
1268
[email protected]939e7362010-05-13 20:49:101269 // Gets the type of a uniform for a location in the current program. Sets GL
1270 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361271 // program is valid and the location exists. Adjusts count so it
1272 // does not overflow the uniform.
[email protected]9b1f1b52014-03-12 10:40:131273 bool PrepForSetUniformByLocation(GLint fake_location,
1274 const char* function_name,
1275 Program::UniformApiType api_type,
1276 GLint* real_location,
1277 GLenum* type,
1278 GLsizei* count);
[email protected]939e7362010-05-13 20:49:101279
[email protected]b177ae22011-11-01 03:29:111280 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021281 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111282
[email protected]b273e432010-04-12 17:23:581283 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1284 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1285
[email protected]ac77603c72013-03-08 13:52:061286 // Helper for glGetVertexAttrib
1287 void GetVertexAttribHelper(
1288 const VertexAttrib* attrib, GLenum pname, GLint* param);
1289
[email protected]3916c97e2010-02-25 03:20:501290 // Wrapper for glActiveTexture
1291 void DoActiveTexture(GLenum texture_unit);
1292
[email protected]ae51d192010-04-27 00:48:031293 // Wrapper for glAttachShader
1294 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1295
[email protected]96449d2c2009-11-25 00:01:321296 // Wrapper for glBindBuffer since we need to track the current targets.
1297 void DoBindBuffer(GLenum target, GLuint buffer);
1298
[email protected]86093972010-03-11 00:13:561299 // Wrapper for glBindFramebuffer since we need to track the current targets.
1300 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1301
1302 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1303 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1304
[email protected]a93bb842010-02-16 23:03:471305 // Wrapper for glBindTexture since we need to track the current targets.
1306 void DoBindTexture(GLenum target, GLuint texture);
1307
[email protected]944b62f32012-09-27 02:20:461308 // Wrapper for glBindVertexArrayOES
1309 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571310 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461311
[email protected]49cabed2013-11-13 18:15:181312 // Wrapper for glBlitFramebufferCHROMIUM.
1313 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301314 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1315 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1316 GLbitfield mask, GLenum filter);
1317
[email protected]36cef8ce2010-03-16 07:34:451318 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111319 void DoBufferSubData(
1320 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1321
[email protected]36cef8ce2010-03-16 07:34:451322 // Wrapper for glCheckFramebufferStatus
1323 GLenum DoCheckFramebufferStatus(GLenum target);
1324
[email protected]3a03a8f2011-03-19 00:51:271325 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081326 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271327
[email protected]88a61bf2012-10-27 13:00:421328 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421329 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251330 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281331
[email protected]45bf5152010-02-12 00:11:311332 // Wrapper for glCompileShader.
1333 void DoCompileShader(GLuint shader);
1334
[email protected]ae51d192010-04-27 00:48:031335 // Wrapper for glDetachShader
1336 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1337
[email protected]3a2e7c7b2010-08-06 01:12:281338 // Wrapper for glDisable
1339 void DoDisable(GLenum cap);
1340
[email protected]07f54fcc2009-12-22 02:46:301341 // Wrapper for glDisableVertexAttribArray.
1342 void DoDisableVertexAttribArray(GLuint index);
1343
[email protected]60f22d32012-12-12 00:31:581344 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1345 // attachments.
1346 void DoDiscardFramebufferEXT(GLenum target,
1347 GLsizei numAttachments,
1348 const GLenum* attachments);
1349
[email protected]3a2e7c7b2010-08-06 01:12:281350 // Wrapper for glEnable
1351 void DoEnable(GLenum cap);
1352
[email protected]07f54fcc2009-12-22 02:46:301353 // Wrapper for glEnableVertexAttribArray.
1354 void DoEnableVertexAttribArray(GLuint index);
1355
[email protected]882ba1e22012-03-08 19:02:531356 // Wrapper for glFinish.
1357 void DoFinish();
1358
1359 // Wrapper for glFlush.
1360 void DoFlush();
1361
[email protected]36cef8ce2010-03-16 07:34:451362 // Wrapper for glFramebufferRenderbufffer.
1363 void DoFramebufferRenderbuffer(
1364 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1365 GLuint renderbuffer);
1366
1367 // Wrapper for glFramebufferTexture2D.
1368 void DoFramebufferTexture2D(
1369 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1370 GLint level);
1371
[email protected]7d3c36e2013-07-12 14:13:161372 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1373 void DoFramebufferTexture2DMultisample(
1374 GLenum target, GLenum attachment, GLenum textarget,
1375 GLuint texture, GLint level, GLsizei samples);
1376
1377 // Common implementation for both DoFramebufferTexture2D wrappers.
1378 void DoFramebufferTexture2DCommon(const char* name,
1379 GLenum target, GLenum attachment, GLenum textarget,
1380 GLuint texture, GLint level, GLsizei samples);
1381
zmo84c08202014-11-23 15:28:401382 // Wrapper for glFramebufferTextureLayer.
1383 void DoFramebufferTextureLayer(
1384 GLenum target, GLenum attachment, GLuint texture, GLint level,
1385 GLint layer);
1386
[email protected]a93bb842010-02-16 23:03:471387 // Wrapper for glGenerateMipmap
1388 void DoGenerateMipmap(GLenum target);
1389
[email protected]7d3c36e2013-07-12 14:13:161390 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1391 // to account for different pname values defined in different extension
1392 // variants.
1393 GLenum AdjustGetPname(GLenum pname);
1394
[email protected]b273e432010-04-12 17:23:581395 // Wrapper for DoGetBooleanv.
1396 void DoGetBooleanv(GLenum pname, GLboolean* params);
1397
1398 // Wrapper for DoGetFloatv.
1399 void DoGetFloatv(GLenum pname, GLfloat* params);
1400
[email protected]36cef8ce2010-03-16 07:34:451401 // Wrapper for glGetFramebufferAttachmentParameteriv.
1402 void DoGetFramebufferAttachmentParameteriv(
1403 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1404
[email protected]a0c3e972010-04-21 00:49:131405 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581406 void DoGetIntegerv(GLenum pname, GLint* params);
1407
[email protected]29a9eb52010-04-13 09:04:231408 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061409 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231410 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1411
[email protected]17cfbe0e2013-03-07 01:26:081412 // Wrapper for glGetBufferParameteriv.
1413 void DoGetBufferParameteriv(
1414 GLenum target, GLenum pname, GLint* params);
1415
[email protected]a0c3e972010-04-21 00:49:131416 // Wrapper for glGetProgramiv.
1417 void DoGetProgramiv(
1418 GLuint program_id, GLenum pname, GLint* params);
1419
[email protected]36cef8ce2010-03-16 07:34:451420 // Wrapper for glRenderbufferParameteriv.
1421 void DoGetRenderbufferParameteriv(
1422 GLenum target, GLenum pname, GLint* params);
1423
[email protected]ddd968b82010-03-02 00:44:291424 // Wrapper for glGetShaderiv
1425 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1426
[email protected]4c6f5462014-03-05 00:26:561427 // Wrappers for glGetTexParameter.
1428 void DoGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
1429 void DoGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
1430 void InitTextureMaxAnisotropyIfNeeded(GLenum target, GLenum pname);
1431
[email protected]b1122982010-05-17 23:04:241432 // Wrappers for glGetVertexAttrib.
1433 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1434 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1435
[email protected]1958e0e2010-04-22 05:17:151436 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241437 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151438 bool DoIsBuffer(GLuint client_id);
1439 bool DoIsFramebuffer(GLuint client_id);
1440 bool DoIsProgram(GLuint client_id);
1441 bool DoIsRenderbuffer(GLuint client_id);
1442 bool DoIsShader(GLuint client_id);
1443 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461444 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151445
[email protected]07f54fcc2009-12-22 02:46:301446 // Wrapper for glLinkProgram
1447 void DoLinkProgram(GLuint program);
1448
[email protected]36cef8ce2010-03-16 07:34:451449 // Wrapper for glRenderbufferStorage.
1450 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031451 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451452
[email protected]49cabed2013-11-13 18:15:181453 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1454 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301455 GLenum target, GLsizei samples, GLenum internalformat,
1456 GLsizei width, GLsizei height);
1457
[email protected]49cabed2013-11-13 18:15:181458 // Handler for glRenderbufferStorageMultisampleEXT
1459 // (multisampled_render_to_texture).
1460 void DoRenderbufferStorageMultisampleEXT(
1461 GLenum target, GLsizei samples, GLenum internalformat,
1462 GLsizei width, GLsizei height);
1463
1464 // Common validation for multisample extensions.
1465 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1466 GLenum internalformat,
1467 GLsizei width,
1468 GLsizei height);
1469
[email protected]4a4c18b2013-09-13 22:50:101470 // Verifies that the currently bound multisample renderbuffer is valid
1471 // Very slow! Only done on platforms with driver bugs that return invalid
1472 // buffers under memory pressure
1473 bool VerifyMultisampleRenderbufferIntegrity(
1474 GLuint renderbuffer, GLenum format);
1475
[email protected]b273e432010-04-12 17:23:581476 // Wrapper for glReleaseShaderCompiler.
1477 void DoReleaseShaderCompiler() { }
1478
zmobcb3fdd62014-12-11 00:49:031479 // Wrappers for glSamplerParameter*v functions.
1480 void DoSamplerParameterfv(
1481 GLuint sampler, GLenum pname, const GLfloat* params);
1482 void DoSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* params);
1483
[email protected]3916c97e2010-02-25 03:20:501484 // Wrappers for glTexParameter functions.
1485 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1486 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1487 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1488 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1489
1490 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1491 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121492 void DoUniform1i(GLint fake_location, GLint v0);
1493 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1494 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1495 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1496 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101497
1498 // Wrappers for glUniformfv because some drivers don't correctly accept
1499 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121500 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1501 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1502 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1503 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501504
[email protected]43c2f1f2011-03-25 18:35:361505 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121506 GLint fake_location, GLsizei count, GLboolean transpose,
1507 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361508 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121509 GLint fake_location, GLsizei count, GLboolean transpose,
1510 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361511 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121512 GLint fake_location, GLsizei count, GLboolean transpose,
1513 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361514
[email protected]af6380962012-11-29 23:24:131515 bool SetVertexAttribValue(
1516 const char* function_name, GLuint index, const GLfloat* value);
1517
[email protected]b1122982010-05-17 23:04:241518 // Wrappers for glVertexAttrib??
1519 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1520 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1521 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1522 void DoVertexAttrib4f(
1523 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1524 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1525 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1526 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1527 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1528
[email protected]43410e92012-04-20 17:06:281529 // Wrapper for glViewport
1530 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1531
[email protected]07f54fcc2009-12-22 02:46:301532 // Wrapper for glUseProgram
1533 void DoUseProgram(GLuint program);
1534
[email protected]ae51d192010-04-27 00:48:031535 // Wrapper for glValidateProgram.
1536 void DoValidateProgram(GLuint program_client_id);
1537
[email protected]d2a0e1a2012-08-12 02:25:011538 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1539 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1540 void DoPopGroupMarkerEXT(void);
1541
[email protected]4e8a5b122010-05-08 22:00:101542 // Gets the number of values that will be returned by glGetXXX. Returns
1543 // false if pname is unknown.
1544 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1545
[email protected]07f54fcc2009-12-22 02:46:301546 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431547 bool IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:101548 const char* function_name, GLuint max_vertex_accessed, bool instanced,
1549 GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301550
[email protected]c13e1da62011-09-09 21:48:301551 // Returns true if successful, simulated will be true if attrib0 was
1552 // simulated.
[email protected]c6aef902012-02-14 03:31:421553 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431554 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]3fc38e22014-05-30 00:13:231555 void RestoreStateForAttrib(GLuint attrib, bool restore_array_binding);
[email protected]b1122982010-05-17 23:04:241556
[email protected]91c94eb2013-10-22 10:32:541557 // If an image is bound to texture, this will call Will/DidUseTexImage
1558 // if needed.
1559 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1560 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1561
1562 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111563 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541564 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501565
[email protected]8fbedc02010-11-18 18:43:401566 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421567 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431568 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421569 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401570 void RestoreStateForSimulatedFixedAttribs();
1571
[email protected]c6aef902012-02-14 03:31:421572 // Handle DrawArrays and DrawElements for both instanced and non-instanced
[email protected]ac6904d62014-07-30 12:00:101573 // cases (primcount is always 1 for non-instanced).
[email protected]c6aef902012-02-14 03:31:421574 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431575 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421576 bool instanced, GLenum mode, GLint first, GLsizei count,
1577 GLsizei primcount);
1578 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431579 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421580 bool instanced, GLenum mode, GLsizei count, GLenum type,
1581 int32 offset, GLsizei primcount);
1582
[email protected]61eeb33f2011-07-26 15:30:311583 GLenum GetBindTargetForSamplerType(GLenum type) {
1584 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461585 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1586 switch (type) {
1587 case GL_SAMPLER_2D:
1588 return GL_TEXTURE_2D;
1589 case GL_SAMPLER_CUBE:
1590 return GL_TEXTURE_CUBE_MAP;
1591 case GL_SAMPLER_EXTERNAL_OES:
1592 return GL_TEXTURE_EXTERNAL_OES;
1593 case GL_SAMPLER_2D_RECT_ARB:
1594 return GL_TEXTURE_RECTANGLE_ARB;
1595 }
1596
1597 NOTREACHED();
1598 return 0;
[email protected]61eeb33f2011-07-26 15:30:311599 }
1600
[email protected]8e3e0662010-08-23 18:46:301601 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061602 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1603 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301604 switch (target) {
1605 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451606 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341607 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301608 break;
[email protected]ebfb73c2012-08-15 02:37:451609 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341610 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301611 break;
1612 default:
1613 NOTREACHED();
1614 break;
1615 }
[email protected]4d8f0dd2013-03-09 14:37:061616 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301617 }
1618
[email protected]ed9f9cd2013-02-27 21:12:351619 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201620 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271621 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201622 switch (target) {
1623 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111624 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201625 break;
1626 default:
1627 NOTREACHED();
1628 break;
1629 }
[email protected]ee2a79c32013-03-10 03:50:271630 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201631 }
1632
[email protected]f7b85372010-02-03 01:11:371633 // Validates the program and location for a glGetUniform call and returns
1634 // a SizeResult setup to receive the result. Returns true if glGetUniform
1635 // should be called.
1636 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121637 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371638 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121639 error::Error* error, GLint* real_location, GLuint* service_id,
1640 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371641
jbauman7a059312014-10-16 19:30:541642 void MaybeExitOnContextLost();
dcheng1f4d1d72014-10-21 16:21:581643 bool WasContextLost() override;
1644 bool WasContextLostByRobustnessExtension() override;
1645 void LoseContext(uint32 reset_status) override;
[email protected]38d139d2011-07-14 00:38:431646
[email protected]e51bdf32011-11-23 22:21:461647#if defined(OS_MACOSX)
1648 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1649#endif
1650
[email protected]ad84a3a2012-06-08 21:42:431651 bool ValidateCompressedTexDimensions(
1652 const char* function_name,
1653 GLint level, GLsizei width, GLsizei height, GLenum format);
1654 bool ValidateCompressedTexFuncData(
1655 const char* function_name,
1656 GLsizei width, GLsizei height, GLenum format, size_t size);
1657 bool ValidateCompressedTexSubDimensions(
1658 const char* function_name,
1659 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1660 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351661 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431662
[email protected]ab09b612013-03-11 22:11:511663 void RenderWarning(const char* filename, int line, const std::string& msg);
1664 void PerformanceWarning(
1665 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011666
[email protected]62e155e2012-10-23 22:43:151667 const FeatureInfo::FeatureFlags& features() const {
1668 return feature_info_->feature_flags();
1669 }
1670
1671 const FeatureInfo::Workarounds& workarounds() const {
1672 return feature_info_->workarounds();
1673 }
1674
[email protected]a7266a92012-06-28 02:11:081675 bool ShouldDeferDraws() {
1676 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341677 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081678 surface_->DeferDraws();
1679 }
1680
[email protected]09e17272012-11-30 10:30:441681 bool ShouldDeferReads() {
1682 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341683 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441684 surface_->DeferDraws();
1685 }
1686
dongseong.hwange1cb2aa2015-02-11 09:33:331687 bool IsRobustnessSupported() {
1688 return has_robustness_extension_ &&
1689 context_->WasAllocatedUsingRobustnessExtension();
1690 }
1691
[email protected]c76fe672013-12-13 23:30:221692 error::Error WillAccessBoundFramebufferForDraw() {
1693 if (ShouldDeferDraws())
1694 return error::kDeferCommandUntilLater;
1695 if (!offscreen_target_frame_buffer_.get() &&
1696 !framebuffer_state_.bound_draw_framebuffer.get() &&
1697 !surface_->SetBackbufferAllocation(true))
1698 return error::kLostContext;
1699 return error::kNoError;
1700 }
1701
1702 error::Error WillAccessBoundFramebufferForRead() {
1703 if (ShouldDeferReads())
1704 return error::kDeferCommandUntilLater;
1705 if (!offscreen_target_frame_buffer_.get() &&
1706 !framebuffer_state_.bound_read_framebuffer.get() &&
1707 !surface_->SetBackbufferAllocation(true))
1708 return error::kLostContext;
1709 return error::kNoError;
1710 }
1711
vmiura8266ca72014-09-09 21:37:001712 // Set remaining commands to process to 0 to force DoCommands to return
1713 // and allow context preemption and GPU watchdog checks in GpuScheduler().
1714 void ExitCommandProcessingEarly() { commands_to_process_ = 0; }
1715
[email protected]5a36dc132013-07-23 23:17:551716 void ProcessPendingReadPixels();
1717 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1718
[email protected]96449d2c2009-11-25 00:01:321719 // Generate a member function prototype for each command in an automated and
1720 // typesafe way.
vmiuracd108592014-09-08 14:36:341721#define GLES2_CMD_OP(name) \
1722 Error Handle##name(uint32 immediate_data_size, const void* data);
[email protected]96449d2c2009-11-25 00:01:321723
1724 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1725
1726 #undef GLES2_CMD_OP
1727
[email protected]2f2d7042010-04-14 21:45:581728 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381729 scoped_refptr<gfx::GLSurface> surface_;
1730 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021731
[email protected]a3ded6d2010-10-19 06:44:391732 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351733 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391734
[email protected]1d82e822013-04-10 21:32:321735 DebugMarkerManager debug_marker_manager_;
1736 Logger logger_;
1737
[email protected]e259eb412012-10-13 05:47:241738 // All the state for this context.
1739 ContextState state_;
1740
[email protected]34ff8b0c2010-10-01 20:06:021741 // Current width and height of the offscreen frame buffer.
1742 gfx::Size offscreen_size_;
1743
[email protected]96449d2c2009-11-25 00:01:321744 // Util to help with GL.
1745 GLES2Util util_;
1746
[email protected]43410e92012-04-20 17:06:281747 // unpack flip y as last set by glPixelStorei
1748 bool unpack_flip_y_;
1749
[email protected]6c75c712012-06-19 15:43:171750 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281751 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171752 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281753
[email protected]b1122982010-05-17 23:04:241754 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1755 GLuint attrib_0_buffer_id_;
1756
1757 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131758 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241759
[email protected]fc753442011-02-04 19:49:491760 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1761 bool attrib_0_buffer_matches_value_;
1762
[email protected]b1122982010-05-17 23:04:241763 // The size of attrib 0.
1764 GLsizei attrib_0_size_;
1765
[email protected]8fbedc02010-11-18 18:43:401766 // The buffer used to simulate GL_FIXED attribs.
1767 GLuint fixed_attrib_buffer_id_;
1768
1769 // The size of fiixed attrib buffer.
1770 GLsizei fixed_attrib_buffer_size_;
1771
[email protected]b9363b22010-06-09 22:06:151772 // The offscreen frame buffer that the client renders to. With EGL, the
1773 // depth and stencil buffers are separate. With regular GL there is a single
1774 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1775 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351776 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1777 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1778 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1779 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1780 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021781 GLenum offscreen_target_color_format_;
1782 GLenum offscreen_target_depth_format_;
1783 GLenum offscreen_target_stencil_format_;
1784 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561785 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351786
[email protected]de26b3c2011-08-03 21:54:271787 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351788 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1789 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491790 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351791 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271792
1793 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351794 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1795 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051796 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351797
[email protected]882ba1e22012-03-08 19:02:531798 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531799
[email protected]944b62f32012-09-27 02:20:461800 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1801
[email protected]b63f1d62014-07-18 15:40:591802 scoped_ptr<ImageManager> image_manager_;
1803
[email protected]729c0b42013-05-26 02:05:071804 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001805
[email protected]840a7e462013-02-27 01:29:511806 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481807
[email protected]e3932abb2013-03-13 00:01:371808 ShaderCacheCallback shader_cache_callback_;
1809
[email protected]85a4ac22013-05-31 01:58:471810 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421811
[email protected]32fe9aa2011-01-21 23:47:131812 // The format of the back buffer_
1813 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461814 bool back_buffer_has_depth_;
1815 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131816
achaulkcf5316f2014-09-26 19:28:421817 bool surfaceless_;
1818
[email protected]60f22d32012-12-12 00:31:581819 // Backbuffer attachments that are currently undefined.
1820 uint32 backbuffer_needs_clear_bits_;
1821
[email protected]a6a09f852014-05-23 13:05:031822 // The current decoder error communicates the decoder error through command
1823 // processing functions that do not return the error value. Should be set only
1824 // if not returning an error.
[email protected]a3a93e7b2010-08-28 00:48:561825 error::Error current_decoder_error_;
1826
[email protected]b1d2dcb2010-05-17 19:24:181827 bool use_shader_translator_;
dyen0ff9e4402015-02-12 22:27:431828 scoped_refptr<ShaderTranslatorInterface> vertex_translator_;
1829 scoped_refptr<ShaderTranslatorInterface> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181830
[email protected]e82fb792011-09-22 00:33:291831 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411832
[email protected]915a59a12010-09-30 21:29:111833 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051834 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351835 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051836
[email protected]65225772011-05-12 21:10:241837 int frame_number_;
1838
vmiura8266ca72014-09-09 21:37:001839 // Number of commands remaining to be processed in DoCommands().
1840 int commands_to_process_;
1841
[email protected]706b69f2012-07-27 04:59:301842 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431843 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221844 bool reset_by_robustness_extension_;
[email protected]b381ee32014-03-22 02:43:431845 bool supports_post_sub_buffer_;
[email protected]38d139d2011-07-14 00:38:431846
[email protected]f0d74742011-10-03 16:31:041847 // These flags are used to override the state of the shared feature_info_
1848 // member. Because the same FeatureInfo instance may be shared among many
1849 // contexts, the assumptions on the availablity of extensions in WebGL
1850 // contexts may be broken. These flags override the shared state to preserve
1851 // WebGL semantics.
1852 bool force_webgl_glsl_validation_;
1853 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491854 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131855 bool draw_buffers_explicitly_enabled_;
[email protected]93c2fd82014-04-16 02:46:061856 bool shader_texture_lod_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041857
[email protected]062c38b2012-01-18 03:25:101858 bool compile_shader_always_succeeds_;
1859
[email protected]828a3932014-04-02 14:43:131860 // An optional behaviour to lose the context and group when OOM.
1861 bool lose_context_when_out_of_memory_;
1862
[email protected]cae20172012-12-07 00:06:191863 // Log extra info.
1864 bool service_logging_;
1865
[email protected]e51bdf32011-11-23 22:21:461866#if defined(OS_MACOSX)
[email protected]c3a6b4a2014-06-04 09:25:531867 typedef std::map<GLuint, IOSurfaceRef> TextureToIOSurfaceMap;
[email protected]e51bdf32011-11-23 22:21:461868 TextureToIOSurfaceMap texture_to_io_surface_map_;
1869#endif
1870
[email protected]43410e92012-04-20 17:06:281871 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
sievers2384f2b2014-11-18 02:10:351872 scoped_ptr<ClearFramebufferResourceManager> clear_framebuffer_blit_;
[email protected]43410e92012-04-20 17:06:281873
[email protected]1868a342012-11-07 15:56:021874 // Cached values of the currently assigned viewport dimensions.
1875 GLsizei viewport_max_width_;
1876 GLsizei viewport_max_height_;
1877
[email protected]63b465922012-09-06 02:04:521878 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521879 base::TimeDelta total_processing_commands_time_;
1880
[email protected]c986af502013-08-14 01:04:441881 // States related to each manager.
1882 DecoderTextureState texture_state_;
1883 DecoderFramebufferState framebuffer_state_;
1884
[email protected]fb97b662013-02-20 23:02:141885 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131886 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
vmiura1c2b1de2014-09-19 19:03:241887 const unsigned char* cb_command_trace_category_;
dyencb86f2f2014-12-09 18:35:411888 const unsigned char* gpu_decoder_category_;
[email protected]cac16542014-01-15 17:53:511889 int gpu_trace_level_;
1890 bool gpu_trace_commands_;
vmiura1c2b1de2014-09-19 19:03:241891 bool gpu_debug_commands_;
[email protected]94307712012-11-16 23:26:111892
[email protected]5a36dc132013-07-23 23:17:551893 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1894
[email protected]4a4c18b2013-09-13 22:50:101895 // Used to validate multisample renderbuffers if needed
1896 GLuint validation_texture_;
1897 GLuint validation_fbo_multisample_;
1898 GLuint validation_fbo_;
1899
vmiuracd108592014-09-08 14:36:341900 typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
1901 uint32 immediate_data_size,
1902 const void* data);
1903
1904 // A struct to hold info about each command.
1905 struct CommandInfo {
1906 CmdHandler cmd_handler;
1907 uint8 arg_flags; // How to handle the arguments for this command
1908 uint8 cmd_flags; // How to handle this command
1909 uint16 arg_count; // How many arguments are expected for this command.
1910 };
1911
1912 // A table of CommandInfo for all the commands.
1913 static const CommandInfo command_info[kNumCommands - kStartPoint];
1914
[email protected]96449d2c2009-11-25 00:01:321915 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1916};
1917
vmiuracd108592014-09-08 14:36:341918const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
1919#define GLES2_CMD_OP(name) \
1920 { \
1921 &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags, \
1922 cmds::name::cmd_flags, \
1923 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
1924 } \
1925 , /* NOLINT */
1926 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1927#undef GLES2_CMD_OP
1928};
1929
[email protected]ab09b612013-03-11 22:11:511930ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301931 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511932 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301933 error_state_(error_state) {
1934 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351935}
1936
1937ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301938 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351939}
1940
[email protected]2b10c02d2014-01-29 16:43:021941static void RestoreCurrentTextureBindings(ContextState* state, GLenum target) {
[email protected]ce296892013-10-24 22:04:361942 TextureUnit& info = state->texture_units[0];
1943 GLuint last_id;
[email protected]2b10c02d2014-01-29 16:43:021944 scoped_refptr<TextureRef> texture_ref;
1945 switch (target) {
1946 case GL_TEXTURE_2D:
1947 texture_ref = info.bound_texture_2d;
1948 break;
1949 case GL_TEXTURE_CUBE_MAP:
1950 texture_ref = info.bound_texture_cube_map;
1951 break;
1952 case GL_TEXTURE_EXTERNAL_OES:
1953 texture_ref = info.bound_texture_external_oes;
1954 break;
1955 case GL_TEXTURE_RECTANGLE_ARB:
1956 texture_ref = info.bound_texture_rectangle_arb;
1957 break;
1958 default:
1959 NOTREACHED();
1960 break;
1961 }
1962 if (texture_ref.get()) {
1963 last_id = texture_ref->service_id();
[email protected]ce296892013-10-24 22:04:361964 } else {
1965 last_id = 0;
1966 }
1967
[email protected]2b10c02d2014-01-29 16:43:021968 glBindTexture(target, last_id);
[email protected]ce296892013-10-24 22:04:361969 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1970}
1971
[email protected]2b10c02d2014-01-29 16:43:021972ScopedTextureBinder::ScopedTextureBinder(ContextState* state,
1973 GLuint id,
1974 GLenum target)
1975 : state_(state),
1976 target_(target) {
[email protected]ab09b612013-03-11 22:11:511977 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021978 "ScopedTextureBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351979
1980 // TODO(apatrick): Check if there are any other states that need to be reset
1981 // before binding a new texture.
1982 glActiveTexture(GL_TEXTURE0);
[email protected]2b10c02d2014-01-29 16:43:021983 glBindTexture(target, id);
[email protected]6217d392010-03-25 22:08:351984}
1985
[email protected]2b10c02d2014-01-29 16:43:021986ScopedTextureBinder::~ScopedTextureBinder() {
[email protected]ab09b612013-03-11 22:11:511987 ScopedGLErrorSuppressor suppressor(
[email protected]2b10c02d2014-01-29 16:43:021988 "ScopedTextureBinder::dtor", state_->GetErrorState());
1989 RestoreCurrentTextureBindings(state_, target_);
[email protected]6217d392010-03-25 22:08:351990}
1991
[email protected]18e785a2013-10-09 03:29:411992ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351993 GLuint id)
[email protected]18e785a2013-10-09 03:29:411994 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511995 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411996 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351997 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1998}
1999
2000ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:512001 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:412002 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
2003 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:352004}
2005
2006ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
2007 GLuint id)
2008 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:512009 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302010 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352011 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:452012 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:352013}
2014
2015ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:512016 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302017 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:302018 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:352019}
2020
[email protected]34ff8b0c2010-10-01 20:06:022021ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:272022 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:522023 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:342024 resolve_and_bind_ = (
2025 decoder_->offscreen_target_frame_buffer_.get() &&
2026 decoder_->IsOffscreenBufferMultisampled() &&
2027 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
2028 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:022029 if (!resolve_and_bind_)
2030 return;
2031
[email protected]ab09b612013-03-11 22:11:512032 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302033 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022034 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
2035 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:272036 GLuint targetid;
2037 if (internal) {
2038 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
2039 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:352040 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:272041 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:352042 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:362043 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:272044 decoder_->offscreen_resolved_color_texture_->Create();
2045
2046 DCHECK(decoder_->offscreen_saved_color_format_);
2047 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:092048 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
2049 false);
[email protected]de26b3c2011-08-03 21:54:272050 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
2051 decoder_->offscreen_resolved_color_texture_.get());
2052 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
2053 GL_FRAMEBUFFER_COMPLETE) {
2054 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
2055 << "because offscreen resolved FBO was incomplete.";
2056 return;
2057 }
2058 }
2059 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
2060 } else {
2061 targetid = decoder_->offscreen_saved_frame_buffer_->id();
2062 }
2063 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022064 const int width = decoder_->offscreen_size_.width();
2065 const int height = decoder_->offscreen_size_.height();
[email protected]454157e2014-05-03 02:49:452066 decoder->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f42f05b2013-11-15 21:46:182067 decoder->BlitFramebufferHelper(0,
2068 0,
2069 width,
2070 height,
2071 0,
2072 0,
2073 width,
2074 height,
2075 GL_COLOR_BUFFER_BIT,
2076 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:272077 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:022078}
2079
2080ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
2081 if (!resolve_and_bind_)
2082 return;
2083
[email protected]ab09b612013-03-11 22:11:512084 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302085 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:022086 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:222087 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:452088 decoder_->state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]8c3e68782010-10-27 16:41:182089 }
[email protected]34ff8b0c2010-10-01 20:06:022090}
2091
[email protected]ce296892013-10-24 22:04:362092BackTexture::BackTexture(
2093 MemoryTracker* memory_tracker,
2094 ContextState* state)
2095 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2096 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482097 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252098 id_(0) {
[email protected]6217d392010-03-25 22:08:352099}
2100
[email protected]ed9f9cd2013-02-27 21:12:352101BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:352102 // This does not destroy the render texture because that would require that
2103 // the associated GL context was current. Just check that it was explicitly
2104 // destroyed.
2105 DCHECK_EQ(id_, 0u);
2106}
2107
[email protected]ed9f9cd2013-02-27 21:12:352108void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:302109 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:362110 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352111 Destroy();
2112 glGenTextures(1, &id_);
[email protected]2b10c02d2014-01-29 16:43:022113 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]eeeb07b92014-08-16 07:46:262114 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
[email protected]3a4d0c52011-06-29 23:11:582116 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2117 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:162118
2119 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
2120 // never called on an offscreen context, no data will ever be uploaded to the
2121 // saved offscreen color texture (it is deferred until to when SwapBuffers
2122 // is called). My idea is that some nvidia drivers might have a bug where
2123 // deleting a texture that has never been populated might cause a
2124 // crash.
2125 glTexImage2D(
2126 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:482127
2128 bytes_allocated_ = 16u * 16u * 4u;
2129 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:352130}
2131
[email protected]ed9f9cd2013-02-27 21:12:352132bool BackTexture::AllocateStorage(
2133 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:352134 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302135 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:362136 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022137 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]678a73f2012-12-19 19:22:092138 uint32 image_size = 0;
2139 GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:422140 size.width(), size.height(), 1, format, GL_UNSIGNED_BYTE, 8, &image_size,
[email protected]678a73f2012-12-19 19:22:092141 NULL, NULL);
2142
[email protected]7989c9e2013-01-23 06:39:262143 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
2144 return false;
2145 }
2146
[email protected]40d90a22013-04-09 03:39:552147 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:092148 if (zero) {
2149 zero_data.reset(new char[image_size]);
2150 memset(zero_data.get(), 0, image_size);
2151 }
[email protected]6217d392010-03-25 22:08:352152
[email protected]8f1d2aa2013-05-10 23:45:382153 glTexImage2D(GL_TEXTURE_2D,
2154 0, // mip level
2155 format,
2156 size.width(),
2157 size.height(),
2158 0, // border
2159 format,
2160 GL_UNSIGNED_BYTE,
2161 zero_data.get());
[email protected]6217d392010-03-25 22:08:352162
[email protected]d37231fa2010-04-09 21:16:022163 size_ = size;
2164
[email protected]1078f912011-12-23 13:12:142165 bool success = glGetError() == GL_NO_ERROR;
2166 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482167 memory_tracker_.TrackMemFree(bytes_allocated_);
2168 bytes_allocated_ = image_size;
2169 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142170 }
2171 return success;
[email protected]6217d392010-03-25 22:08:352172}
2173
[email protected]ed9f9cd2013-02-27 21:12:352174void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:352175 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302176 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:362177 state_->GetErrorState());
[email protected]2b10c02d2014-01-29 16:43:022178 ScopedTextureBinder binder(state_, id_, GL_TEXTURE_2D);
[email protected]6217d392010-03-25 22:08:352179 glCopyTexImage2D(GL_TEXTURE_2D,
2180 0, // level
[email protected]3a4d0c52011-06-29 23:11:582181 format,
[email protected]6217d392010-03-25 22:08:352182 0, 0,
2183 size.width(),
2184 size.height(),
2185 0); // border
2186}
2187
[email protected]ed9f9cd2013-02-27 21:12:352188void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352189 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302190 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:362191 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352192 glDeleteTextures(1, &id_);
2193 id_ = 0;
2194 }
[email protected]68e81a4a62012-12-13 01:16:482195 memory_tracker_.TrackMemFree(bytes_allocated_);
2196 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352197}
2198
[email protected]ed9f9cd2013-02-27 21:12:352199void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052200 id_ = 0;
2201}
2202
[email protected]d5a28e452013-10-10 01:01:402203BackRenderbuffer::BackRenderbuffer(
2204 RenderbufferManager* renderbuffer_manager,
2205 MemoryTracker* memory_tracker,
2206 ContextState* state)
2207 : renderbuffer_manager_(renderbuffer_manager),
2208 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2209 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482210 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252211 id_(0) {
[email protected]6217d392010-03-25 22:08:352212}
2213
[email protected]ed9f9cd2013-02-27 21:12:352214BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352215 // This does not destroy the render buffer because that would require that
2216 // the associated GL context was current. Just check that it was explicitly
2217 // destroyed.
2218 DCHECK_EQ(id_, 0u);
2219}
2220
[email protected]ed9f9cd2013-02-27 21:12:352221void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302222 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402223 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352224 Destroy();
2225 glGenRenderbuffersEXT(1, &id_);
2226}
2227
[email protected]f42f05b2013-11-15 21:46:182228bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2229 const gfx::Size& size,
2230 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352231 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512232 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402233 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2234 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262235
2236 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402237 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232238 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262239 return false;
2240 }
2241
2242 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2243 return false;
2244 }
2245
[email protected]34ff8b0c2010-10-01 20:06:022246 if (samples <= 1) {
2247 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2248 format,
2249 size.width(),
2250 size.height());
2251 } else {
[email protected]f42f05b2013-11-15 21:46:182252 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2253 GL_RENDERBUFFER,
2254 samples,
2255 format,
2256 size.width(),
2257 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022258 }
[email protected]1078f912011-12-23 13:12:142259 bool success = glGetError() == GL_NO_ERROR;
2260 if (success) {
[email protected]d5a28e452013-10-10 01:01:402261 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482262 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262263 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402264 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482265 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142266 }
2267 return success;
[email protected]6217d392010-03-25 22:08:352268}
2269
[email protected]ed9f9cd2013-02-27 21:12:352270void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352271 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302272 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402273 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352274 glDeleteRenderbuffersEXT(1, &id_);
2275 id_ = 0;
2276 }
[email protected]68e81a4a62012-12-13 01:16:482277 memory_tracker_.TrackMemFree(bytes_allocated_);
2278 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352279}
2280
[email protected]ed9f9cd2013-02-27 21:12:352281void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052282 id_ = 0;
2283}
2284
[email protected]ed9f9cd2013-02-27 21:12:352285BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352286 : decoder_(decoder),
2287 id_(0) {
2288}
2289
[email protected]ed9f9cd2013-02-27 21:12:352290BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352291 // This does not destroy the frame buffer because that would require that
2292 // the associated GL context was current. Just check that it was explicitly
2293 // destroyed.
2294 DCHECK_EQ(id_, 0u);
2295}
2296
[email protected]ed9f9cd2013-02-27 21:12:352297void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302298 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2299 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352300 Destroy();
2301 glGenFramebuffersEXT(1, &id_);
2302}
2303
[email protected]ed9f9cd2013-02-27 21:12:352304void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352305 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512306 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302307 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352308 ScopedFrameBufferBinder binder(decoder_, id_);
2309 GLuint attach_id = texture ? texture->id() : 0;
2310 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2311 GL_COLOR_ATTACHMENT0,
2312 GL_TEXTURE_2D,
2313 attach_id,
2314 0);
2315}
2316
[email protected]ed9f9cd2013-02-27 21:12:352317void BackFramebuffer::AttachRenderBuffer(GLenum target,
2318 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352319 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512320 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302321 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352322 ScopedFrameBufferBinder binder(decoder_, id_);
2323 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2324 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152325 target,
[email protected]6217d392010-03-25 22:08:352326 GL_RENDERBUFFER,
2327 attach_id);
2328}
2329
[email protected]ed9f9cd2013-02-27 21:12:352330void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352331 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302332 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2333 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352334 glDeleteFramebuffersEXT(1, &id_);
2335 id_ = 0;
2336 }
2337}
2338
[email protected]ed9f9cd2013-02-27 21:12:352339void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052340 id_ = 0;
2341}
2342
[email protected]ed9f9cd2013-02-27 21:12:352343GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352344 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302345 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2346 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352347 ScopedFrameBufferBinder binder(decoder_, id_);
2348 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2349}
2350
[email protected]aa7666122011-09-02 19:45:522351GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2352 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322353}
2354
[email protected]aa7666122011-09-02 19:45:522355GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392356 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572357 group_(group),
[email protected]1d82e822013-04-10 21:32:322358 logger_(&debug_marker_manager_),
[email protected]828a3932014-04-02 14:43:132359 state_(group_->feature_info(), this, &logger_),
[email protected]43410e92012-04-20 17:06:282360 unpack_flip_y_(false),
2361 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172362 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242363 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492364 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242365 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402366 fixed_attrib_buffer_id_(0),
2367 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022368 offscreen_target_color_format_(0),
2369 offscreen_target_depth_format_(0),
2370 offscreen_target_stencil_format_(0),
2371 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562372 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052373 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132374 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462375 back_buffer_has_depth_(false),
2376 back_buffer_has_stencil_(false),
achaulkcf5316f2014-09-26 19:28:422377 surfaceless_(false),
[email protected]60f22d32012-12-12 00:31:582378 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562379 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052380 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112381 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002382 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432383 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302384 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512385 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222386 reset_by_robustness_extension_(false),
[email protected]b381ee32014-03-22 02:43:432387 supports_post_sub_buffer_(false),
[email protected]f0d74742011-10-03 16:31:042388 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102389 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492390 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132391 draw_buffers_explicitly_enabled_(false),
[email protected]93c2fd82014-04-16 02:46:062392 shader_texture_lod_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282393 compile_shader_always_succeeds_(false),
[email protected]828a3932014-04-02 14:43:132394 lose_context_when_out_of_memory_(false),
avi9ab037202014-12-22 23:49:532395 service_logging_(base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]cae20172012-12-07 00:06:192396 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022397 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102398 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002399 texture_state_(group_->feature_info()
2400 ->workarounds()
2401 .texsubimage2d_faster_than_teximage2d),
vmiura1c2b1de2014-09-19 19:03:242402 cb_command_trace_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2403 TRACE_DISABLED_BY_DEFAULT("cb_command"))),
dyencb86f2f2014-12-09 18:35:412404 gpu_decoder_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
2405 TRACE_DISABLED_BY_DEFAULT("gpu_decoder"))),
vmiura1c2b1de2014-09-19 19:03:242406 gpu_trace_level_(2),
2407 gpu_trace_commands_(false),
2408 gpu_debug_commands_(false),
[email protected]4a4c18b2013-09-13 22:50:102409 validation_texture_(0),
2410 validation_fbo_multisample_(0),
2411 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572412 DCHECK(group);
2413
[email protected]b1122982010-05-17 23:04:242414 attrib_0_value_.v[0] = 0.0f;
2415 attrib_0_value_.v[1] = 0.0f;
2416 attrib_0_value_.v[2] = 0.0f;
2417 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152418
[email protected]c2f8c8402010-12-06 18:07:242419 // The shader translator is used for WebGL even when running on EGL
2420 // because additional restrictions are needed (like only enabling
2421 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562422 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2423 // the empty string to CompileShader and this is not a valid shader.
2424 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
avi9ab037202014-12-22 23:49:532425 base::CommandLine::ForCurrentProcess()->HasSwitch(
[email protected]39ba4f02012-03-26 01:16:002426 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152427 use_shader_translator_ = false;
2428 }
[email protected]96449d2c2009-11-25 00:01:322429}
2430
[email protected]80eb6b52012-01-19 00:14:412431GLES2DecoderImpl::~GLES2DecoderImpl() {
2432}
2433
[email protected]c410da802011-03-14 19:17:412434bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382435 const scoped_refptr<gfx::GLSurface>& surface,
2436 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232437 bool offscreen,
[email protected]c410da802011-03-14 19:17:412438 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292439 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242440 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322441 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382442 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302443 DCHECK(!context_.get());
2444
jbaumana7604692014-10-17 02:00:392445 surfaceless_ = surface->IsSurfaceless() && !offscreen;
achaulkcf5316f2014-09-26 19:28:422446
[email protected]55e136f2013-04-03 18:50:062447 set_initialized();
[email protected]b4af07d2014-08-20 00:11:572448 gpu_tracer_.reset(new GPUTracer(this));
[email protected]8f9b8dd2013-09-12 18:05:132449 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]fb97b662013-02-20 23:02:142450
avi9ab037202014-12-22 23:49:532451 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2452 switches::kEnableGPUDebugging)) {
[email protected]e844ae22012-01-14 03:36:262453 set_debug(true);
2454 }
2455
avi9ab037202014-12-22 23:49:532456 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2457 switches::kEnableGPUCommandLogging)) {
[email protected]39ba4f02012-03-26 01:16:002458 set_log_commands(true);
2459 }
2460
avi9ab037202014-12-22 23:49:532461 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2462 switches::kEnableUnsafeES3APIs)) {
zmo84c08202014-11-23 15:28:402463 set_unsafe_es3_apis_enabled(true);
2464 }
2465
avi9ab037202014-12-22 23:49:532466 compile_shader_always_succeeds_ =
2467 base::CommandLine::ForCurrentProcess()->HasSwitch(
2468 switches::kCompileShaderAlwaysSucceeds);
[email protected]062c38b2012-01-18 03:25:102469
[email protected]63c9b052012-05-17 18:27:382470 // Take ownership of the context and surface. The surface can be replaced with
2471 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382472 context_ = context;
[email protected]63c9b052012-05-17 18:27:382473 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182474
[email protected]65f7efe2013-11-28 03:11:472475 ContextCreationAttribHelper attrib_parser;
2476 if (!attrib_parser.Parse(attribs))
2477 return false;
2478
[email protected]828a3932014-04-02 14:43:132479 // Save the loseContextWhenOutOfMemory context creation attribute.
2480 lose_context_when_out_of_memory_ =
[email protected]845c4e32014-08-13 11:50:402481 attrib_parser.lose_context_when_out_of_memory;
[email protected]828a3932014-04-02 14:43:132482
[email protected]65f7efe2013-11-28 03:11:472483 // If the failIfMajorPerformanceCaveat context creation attribute was true
2484 // and we are using a software renderer, fail.
[email protected]845c4e32014-08-13 11:50:402485 if (attrib_parser.fail_if_major_perf_caveat &&
[email protected]65f7efe2013-11-28 03:11:472486 feature_info_->feature_flags().is_swiftshader) {
2487 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2488 Destroy(true);
2489 return false;
2490 }
2491
[email protected]956aec52013-09-05 15:41:192492 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222493 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392494 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422495 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382496 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032497 return false;
[email protected]a3ded6d2010-10-19 06:44:392498 }
[email protected]b64c24952012-04-19 03:20:272499 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282500
[email protected]e82fb792011-09-22 00:33:292501 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502502
[email protected]af6380962012-11-29 23:24:132503 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]da364812014-05-09 21:39:482504 vertex_array_manager_.reset(new VertexArrayManager());
2505
2506 GLuint default_vertex_attrib_service_id = 0;
2507 if (features().native_vertex_array_object) {
2508 glGenVertexArraysOES(1, &default_vertex_attrib_service_id);
2509 glBindVertexArrayOES(default_vertex_attrib_service_id);
2510 }
2511
2512 state_.default_vertex_attrib_manager =
2513 CreateVertexAttribManager(0, default_vertex_attrib_service_id, false);
2514
[email protected]81f20a622014-04-18 01:54:522515 state_.default_vertex_attrib_manager->Initialize(
[email protected]94ba2e02014-03-12 10:32:002516 group_->max_vertex_attribs(),
2517 feature_info_->workarounds().init_vertex_attributes);
[email protected]944b62f32012-09-27 02:20:462518
[email protected]81f20a622014-04-18 01:54:522519 // vertex_attrib_manager is set to default_vertex_attrib_manager by this call
[email protected]ab4fd7282012-10-12 16:25:572520 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322521
[email protected]7cd76fd2013-06-02 21:11:112522 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]882ba1e22012-03-08 19:02:532523
[email protected]b63f1d62014-07-18 15:40:592524 image_manager_.reset(new ImageManager);
2525
[email protected]302ce6d2011-07-07 23:28:112526 util_.set_num_compressed_texture_formats(
2527 validators_->compressed_texture_format.GetValues().size());
2528
[email protected]1071e572011-02-09 20:00:122529 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2530 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2531 // OpenGL ES 2.0 does not have this issue.
2532 glEnableVertexAttribArray(0);
2533 }
[email protected]b1122982010-05-17 23:04:242534 glGenBuffersARB(1, &attrib_0_buffer_id_);
2535 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2536 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2537 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402538 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082539
[email protected]1868a342012-11-07 15:56:022540 state_.texture_units.resize(group_->max_texture_units());
2541 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492542 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312543 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492544 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152545 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492546 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072547 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492548 state_.texture_units[tt].bound_texture_external_oes = ref;
[email protected]5ebf59f2014-04-08 03:51:572549 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref ? ref->service_id() : 0);
[email protected]61eeb33f2011-07-26 15:30:312550 }
[email protected]62e155e2012-10-23 22:43:152551 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492552 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072553 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492554 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
[email protected]5ebf59f2014-04-08 03:51:572555 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref ? ref->service_id() : 0);
[email protected]e51bdf32011-11-23 22:21:462556 }
[email protected]370eaf12013-05-18 09:19:492557 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2558 state_.texture_units[tt].bound_texture_cube_map = ref;
[email protected]5ebf59f2014-04-08 03:51:572559 glBindTexture(GL_TEXTURE_CUBE_MAP, ref ? ref->service_id() : 0);
[email protected]370eaf12013-05-18 09:19:492560 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2561 state_.texture_units[tt].bound_texture_2d = ref;
[email protected]5ebf59f2014-04-08 03:51:572562 glBindTexture(GL_TEXTURE_2D, ref ? ref->service_id() : 0);
[email protected]1958e0e2010-04-22 05:17:152563 }
[email protected]00f893d2010-08-24 18:55:492564 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502565 CHECK_GL_ERROR();
2566
[email protected]069944672012-04-25 20:52:232567 if (offscreen) {
[email protected]845c4e32014-08-13 11:50:402568 if (attrib_parser.samples > 0 && attrib_parser.sample_buffers > 0 &&
[email protected]b0609652012-12-14 07:24:542569 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022570 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432571 // max_sample_count must be initialized to a sane value. If
2572 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2573 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022574 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
[email protected]845c4e32014-08-13 11:50:402575 offscreen_target_samples_ = std::min(attrib_parser.samples,
[email protected]34ff8b0c2010-10-01 20:06:022576 max_sample_count);
2577 } else {
2578 offscreen_target_samples_ = 1;
2579 }
[email protected]845c4e32014-08-13 11:50:402580 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved;
[email protected]34ff8b0c2010-10-01 20:06:022581
2582 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2583 const bool rgb8_supported =
2584 context_->HasExtension("GL_OES_rgb8_rgba8");
2585 // The only available default render buffer formats in GLES2 have very
2586 // little precision. Don't enable multisampling unless 8-bit render
2587 // buffer formats are available--instead fall back to 8-bit textures.
2588 if (rgb8_supported && offscreen_target_samples_ > 1) {
[email protected]845c4e32014-08-13 11:50:402589 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022590 GL_RGBA8 : GL_RGB8;
2591 } else {
2592 offscreen_target_samples_ = 1;
[email protected]845c4e32014-08-13 11:50:402593 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022594 GL_RGBA : GL_RGB;
2595 }
2596
2597 // ANGLE only supports packed depth/stencil formats, so use it if it is
2598 // available.
2599 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182600 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272601 VLOG(1) << "GL_OES_packed_depth_stencil "
2602 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]845c4e32014-08-13 11:50:402603 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002604 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022605 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2606 offscreen_target_stencil_format_ = 0;
2607 } else {
2608 // It may be the case that this depth/stencil combination is not
2609 // supported, but this will be checked later by CheckFramebufferStatus.
[email protected]845c4e32014-08-13 11:50:402610 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022611 GL_DEPTH_COMPONENT16 : 0;
[email protected]845c4e32014-08-13 11:50:402612 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022613 GL_STENCIL_INDEX8 : 0;
2614 }
2615 } else {
[email protected]845c4e32014-08-13 11:50:402616 offscreen_target_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022617 GL_RGBA : GL_RGB;
2618
2619 // If depth is requested at all, use the packed depth stencil format if
2620 // it's available, as some desktop GL drivers don't support any non-packed
2621 // formats for depth attachments.
2622 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182623 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272624 VLOG(1) << "GL_EXT_packed_depth_stencil "
2625 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022626
[email protected]845c4e32014-08-13 11:50:402627 if ((attrib_parser.depth_size > 0 || attrib_parser.stencil_size > 0) &&
[email protected]71ee3642010-10-14 18:08:002628 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022629 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2630 offscreen_target_stencil_format_ = 0;
2631 } else {
[email protected]845c4e32014-08-13 11:50:402632 offscreen_target_depth_format_ = attrib_parser.depth_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022633 GL_DEPTH_COMPONENT : 0;
[email protected]845c4e32014-08-13 11:50:402634 offscreen_target_stencil_format_ = attrib_parser.stencil_size > 0 ?
[email protected]34ff8b0c2010-10-01 20:06:022635 GL_STENCIL_INDEX : 0;
2636 }
2637 }
2638
[email protected]845c4e32014-08-13 11:50:402639 offscreen_saved_color_format_ = attrib_parser.alpha_size > 0 ?
[email protected]97872062010-11-03 19:07:052640 GL_RGBA : GL_RGB;
2641
[email protected]6217d392010-03-25 22:08:352642 // Create the target frame buffer. This is the one that the client renders
2643 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352644 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352645 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022646 // Due to GLES2 format limitations, either the color texture (for
2647 // non-multisampling) or the color render buffer (for multisampling) will be
2648 // attached to the offscreen frame buffer. The render buffer has more
2649 // limited formats available to it, but the texture can't do multisampling.
2650 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402651 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2652 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022653 offscreen_target_color_render_buffer_->Create();
2654 } else {
[email protected]ce296892013-10-24 22:04:362655 offscreen_target_color_texture_.reset(new BackTexture(
2656 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022657 offscreen_target_color_texture_->Create();
2658 }
[email protected]d5a28e452013-10-10 01:01:402659 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2660 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152661 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402662 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2663 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152664 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352665
2666 // Create the saved offscreen texture. The target frame buffer is copied
2667 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352668 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022669 offscreen_saved_frame_buffer_->Create();
2670 //
[email protected]ce296892013-10-24 22:04:362671 offscreen_saved_color_texture_.reset(new BackTexture(
2672 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352673 offscreen_saved_color_texture_->Create();
2674
[email protected]6217d392010-03-25 22:08:352675 // Allocate the render buffers at their initial size and check the status
2676 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592677 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012678 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382679 Destroy(true);
[email protected]6217d392010-03-25 22:08:352680 return false;
2681 }
2682
[email protected]678a73f2012-12-19 19:22:092683 // Allocate the offscreen saved color texture.
2684 DCHECK(offscreen_saved_color_format_);
2685 offscreen_saved_color_texture_->AllocateStorage(
2686 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2687
2688 offscreen_saved_frame_buffer_->AttachRenderTexture(
2689 offscreen_saved_color_texture_.get());
2690 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2691 GL_FRAMEBUFFER_COMPLETE) {
2692 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2693 Destroy(true);
2694 return false;
2695 }
2696
[email protected]6217d392010-03-25 22:08:352697 // Bind to the new default frame buffer (the offscreen target frame buffer).
2698 // This should now be associated with ID zero.
2699 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102700 } else {
2701 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2702 // These are NOT if the back buffer has these proprorties. They are
2703 // if we want the command buffer to enforce them regardless of what
2704 // the real backbuffer is assuming the real back buffer gives us more than
2705 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2706 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2707 // can't do anything about that.
2708
achaulkcf5316f2014-09-26 19:28:422709 if (!surfaceless_) {
2710 GLint v = 0;
2711 glGetIntegerv(GL_ALPHA_BITS, &v);
2712 // This checks if the user requested RGBA and we have RGBA then RGBA. If
2713 // the user requested RGB then RGB. If the user did not specify a
2714 // preference than use whatever we were given. Same for DEPTH and STENCIL.
2715 back_buffer_color_format_ =
2716 (attrib_parser.alpha_size != 0 && v > 0) ? GL_RGBA : GL_RGB;
2717 glGetIntegerv(GL_DEPTH_BITS, &v);
2718 back_buffer_has_depth_ = attrib_parser.depth_size != 0 && v > 0;
2719 glGetIntegerv(GL_STENCIL_BITS, &v);
2720 back_buffer_has_stencil_ = attrib_parser.stencil_size != 0 && v > 0;
2721 }
[email protected]6217d392010-03-25 22:08:352722 }
2723
[email protected]76a0ee102010-04-07 21:03:042724 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2725 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2726 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372727 // mailing list archives. It also implicitly enables the desktop GL
2728 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2729 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152730 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2731 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372732 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152733 }
[email protected]de17df392010-04-23 21:09:412734
[email protected]706b69f2012-07-27 04:59:302735 has_robustness_extension_ =
2736 context->HasExtension("GL_ARB_robustness") ||
oetuaho37cc50e2014-10-31 11:19:202737 context->HasExtension("GL_KHR_robustness") ||
[email protected]706b69f2012-07-27 04:59:302738 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432739
[email protected]c2f8c8402010-12-06 18:07:242740 if (!InitializeShaderTranslator()) {
2741 return false;
[email protected]de17df392010-04-23 21:09:412742 }
[email protected]76a0ee102010-04-07 21:03:042743
[email protected]e259eb412012-10-13 05:47:242744 state_.viewport_width = size.width();
2745 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282746
[email protected]5904806b2012-05-08 18:10:222747 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282748 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022749 viewport_max_width_ = viewport_params[0];
2750 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282751
[email protected]88a61bf2012-10-27 13:00:422752 state_.scissor_width = state_.viewport_width;
2753 state_.scissor_height = state_.viewport_height;
2754
[email protected]11f3e702012-06-19 19:00:012755 // Set all the default state because some GL drivers get it wrong.
[email protected]88ba52f2014-04-09 12:39:342756 state_.InitCapabilities(NULL);
2757 state_.InitState(NULL);
[email protected]e259eb412012-10-13 05:47:242758 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012759
2760 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2761 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2762 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2763 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
orglofchcad5a6742014-11-07 19:51:122764 DoBindValueBufferCHROMIUM(GL_SUBSCRIBED_VALUES_BUFFER_CHROMIUM, 0);
[email protected]11f3e702012-06-19 19:00:012765
achaulkcf5316f2014-09-26 19:28:422766 bool call_gl_clear = !surfaceless_;
[email protected]88cfd132013-07-11 00:59:002767#if defined(OS_ANDROID)
2768 // Temporary workaround for Android WebView because this clear ignores the
2769 // clip and corrupts that external UI of the App. Not calling glClear is ok
2770 // because the system already clears the buffer before each draw. Proper
2771 // fix might be setting the scissor clip properly before initialize. See
2772 // crbug.com/259023 for details.
2773 call_gl_clear = surface_->GetHandle();
2774#endif
2775 if (call_gl_clear) {
2776 // Clear the backbuffer.
2777 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2778 }
[email protected]561cc0a62013-05-07 18:34:452779
[email protected]b381ee32014-03-22 02:43:432780 supports_post_sub_buffer_ = surface->SupportsPostSubBuffer();
2781 if (feature_info_->workarounds()
2782 .disable_post_sub_buffers_for_onscreen_surfaces &&
2783 !surface->IsOffscreen())
2784 supports_post_sub_buffer_ = false;
2785
[email protected]62e155e2012-10-23 22:43:152786 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462787 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2788 }
[email protected]dd289a5d62012-06-30 22:05:462789
[email protected]9b753992013-04-27 02:04:412790 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2791 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242792 }
[email protected]85cb4682013-04-20 00:54:242793
[email protected]97419c02013-04-10 02:52:382794 // Only compositor contexts are known to use only the subset of GL
2795 // that can be safely migrated between the iGPU and the dGPU. Mark
2796 // those contexts as safe to forcibly transition between the GPUs.
2797 // http://crbug.com/180876, http://crbug.com/227228
2798 if (!offscreen)
2799 context_->SetSafeToForceGpuSwitch();
2800
[email protected]85a4ac22013-05-31 01:58:472801 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072802 AsyncPixelTransferManager::Create(context.get()));
2803 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592804
sievers2384f2b2014-11-18 02:10:352805 if (workarounds().gl_clear_broken) {
2806 DCHECK(!clear_framebuffer_blit_.get());
2807 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glClearWorkaroundInit");
2808 clear_framebuffer_blit_.reset(new ClearFramebufferResourceManager(this));
2809 if (LOCAL_PEEK_GL_ERROR("glClearWorkaroundInit") != GL_NO_ERROR)
2810 return false;
2811 }
2812
[email protected]91c94eb2013-10-22 10:32:542813 framebuffer_manager()->AddObserver(this);
2814
[email protected]246a70452010-03-05 21:53:502815 return true;
[email protected]96449d2c2009-11-25 00:01:322816}
2817
[email protected]6d668892013-12-04 21:37:122818Capabilities GLES2DecoderImpl::GetCapabilities() {
2819 DCHECK(initialized());
2820
2821 Capabilities caps;
piman1c2e0a852014-11-12 05:17:552822 caps.VisitPrecisions([](GLenum shader, GLenum type,
2823 Capabilities::ShaderPrecision* shader_precision) {
2824 GLint range[2] = {0, 0};
2825 GLint precision = 0;
2826 GetShaderPrecisionFormatImpl(shader, type, range, &precision);
2827 shader_precision->min_range = range[0];
2828 shader_precision->max_range = range[1];
2829 shader_precision->precision = precision;
2830 });
2831 DoGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
2832 &caps.max_combined_texture_image_units);
2833 DoGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &caps.max_cube_map_texture_size);
2834 DoGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS,
2835 &caps.max_fragment_uniform_vectors);
2836 DoGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &caps.max_renderbuffer_size);
2837 DoGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &caps.max_texture_image_units);
2838 DoGetIntegerv(GL_MAX_TEXTURE_SIZE, &caps.max_texture_size);
2839 DoGetIntegerv(GL_MAX_VARYING_VECTORS, &caps.max_varying_vectors);
2840 DoGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &caps.max_vertex_attribs);
2841 DoGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
2842 &caps.max_vertex_texture_image_units);
2843 DoGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS,
2844 &caps.max_vertex_uniform_vectors);
2845 DoGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
2846 &caps.num_compressed_texture_formats);
2847 DoGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &caps.num_shader_binary_formats);
2848 DoGetIntegerv(GL_BIND_GENERATES_RESOURCE_CHROMIUM,
2849 &caps.bind_generates_resource_chromium);
heejin.r.chung8f143292015-02-05 02:44:002850 if (unsafe_es3_apis_enabled()) {
2851 DoGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
2852 &caps.max_transform_feedback_separate_attribs);
2853 DoGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS,
2854 &caps.max_uniform_buffer_bindings);
2855 DoGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT,
2856 &caps.uniform_buffer_offset_alignment);
2857 }
[email protected]6d668892013-12-04 21:37:122858
[email protected]6d668892013-12-04 21:37:122859 caps.egl_image_external =
2860 feature_info_->feature_flags().oes_egl_image_external;
2861 caps.texture_format_bgra8888 =
2862 feature_info_->feature_flags().ext_texture_format_bgra8888;
2863 caps.texture_format_etc1 =
2864 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
aeliasd880a3d2014-08-26 00:46:202865 caps.texture_format_etc1_npot =
2866 caps.texture_format_etc1 && !workarounds().etc1_power_of_two_only;
[email protected]6d668892013-12-04 21:37:122867 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2868 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2869 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2870 caps.discard_framebuffer =
2871 feature_info_->feature_flags().ext_discard_framebuffer;
[email protected]12c99ab02014-04-22 10:12:352872 caps.sync_query = feature_info_->feature_flags().chromium_sync_query;
[email protected]6d668892013-12-04 21:37:122873
2874#if defined(OS_MACOSX)
2875 // This is unconditionally true on mac, no need to test for it at runtime.
2876 caps.iosurface = true;
2877#endif
2878
[email protected]b381ee32014-03-22 02:43:432879 caps.post_sub_buffer = supports_post_sub_buffer_;
reveman340109182014-09-30 15:36:452880 caps.image = true;
[email protected]6d668892013-12-04 21:37:122881
ed9198b422014-10-23 15:01:372882 caps.blend_equation_advanced =
2883 feature_info_->feature_flags().blend_equation_advanced;
2884 caps.blend_equation_advanced_coherent =
2885 feature_info_->feature_flags().blend_equation_advanced_coherent;
hendrikwfc25ca6192014-12-02 06:05:132886 caps.texture_rg = feature_info_->feature_flags().ext_texture_rg;
[email protected]6d668892013-12-04 21:37:122887 return caps;
2888}
2889
[email protected]302ce6d2011-07-07 23:28:112890void GLES2DecoderImpl::UpdateCapabilities() {
2891 util_.set_num_compressed_texture_formats(
2892 validators_->compressed_texture_format.GetValues().size());
2893 util_.set_num_shader_binary_formats(
2894 validators_->shader_binary_format.GetValues().size());
2895}
2896
[email protected]c2f8c8402010-12-06 18:07:242897bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442898 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2899
[email protected]c2f8c8402010-12-06 18:07:242900 if (!use_shader_translator_) {
2901 return true;
2902 }
2903 ShBuiltInResources resources;
2904 ShInitBuiltInResources(&resources);
2905 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2906 resources.MaxVertexUniformVectors =
2907 group_->max_vertex_uniform_vectors();
2908 resources.MaxVaryingVectors = group_->max_varying_vectors();
2909 resources.MaxVertexTextureImageUnits =
2910 group_->max_vertex_texture_image_units();
2911 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2912 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2913 resources.MaxFragmentUniformVectors =
2914 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492915 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242916 resources.MaxExpressionComplexity = 256;
2917 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042918
[email protected]46c86752013-05-21 05:08:392919 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212920 GLint precision = 0;
2921 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2922 range, &precision);
[email protected]448e459e2013-06-12 17:00:412923 resources.FragmentPrecisionHigh =
2924 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142925
[email protected]f0d74742011-10-03 16:31:042926 if (force_webgl_glsl_validation_) {
2927 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492928 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132929 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:442930 if (!draw_buffers_explicitly_enabled_)
2931 resources.MaxDrawBuffers = 1;
[email protected]93c2fd82014-04-16 02:46:062932 resources.EXT_shader_texture_lod = shader_texture_lod_explicitly_enabled_;
oetuaho0decd442014-10-13 08:40:462933 resources.NV_draw_buffers =
2934 draw_buffers_explicitly_enabled_ && features().nv_draw_buffers;
[email protected]f0d74742011-10-03 16:31:042935 } else {
2936 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152937 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462938 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152939 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062940 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152941 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492942 resources.EXT_draw_buffers =
2943 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492944 resources.EXT_frag_depth =
2945 features().ext_frag_depth ? 1 : 0;
[email protected]93c2fd82014-04-16 02:46:062946 resources.EXT_shader_texture_lod =
2947 features().ext_shader_texture_lod ? 1 : 0;
oetuaho0decd442014-10-13 08:40:462948 resources.NV_draw_buffers =
2949 features().nv_draw_buffers ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042950 }
2951
[email protected]26b61442013-03-17 16:12:012952 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2953 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052954 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022955 resources.HashFunction = &CityHash64;
[email protected]6aedcdc2013-01-24 01:25:052956 else
2957 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122958 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2959 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2960 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:212961 int driver_bug_workarounds = 0;
2962 if (workarounds().needs_glsl_built_in_function_emulation)
2963 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:542964 if (workarounds().init_gl_position_in_vertex_shader)
2965 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:112966 if (workarounds().unfold_short_circuit_as_ternary_operation)
2967 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]b03219d2014-02-12 11:17:052968 if (workarounds().init_varyings_without_static_use)
2969 driver_bug_workarounds |= SH_INIT_VARYINGS_WITHOUT_STATIC_USE;
[email protected]f4db2b12014-03-01 03:57:062970 if (workarounds().unroll_for_loop_with_sampler_array_index)
2971 driver_bug_workarounds |= SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
[email protected]711e90802014-07-22 20:40:252972 if (workarounds().scalarize_vec_and_mat_constructor_args)
2973 driver_bug_workarounds |= SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS;
[email protected]fa6d3982014-08-18 18:10:272974 if (workarounds().regenerate_struct_names)
2975 driver_bug_workarounds |= SH_REGENERATE_STRUCT_NAMES;
[email protected]87fb6ab2012-06-13 22:28:042976
avi9ab037202014-12-22 23:49:532977 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2978 switches::kEmulateShaderPrecision))
oetuahoaffd85abe2014-12-11 09:47:092979 resources.WEBGL_debug_shader_precision = true;
2980
[email protected]03cef9b2014-04-03 15:58:142981 vertex_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262982 GL_VERTEX_SHADER,
[email protected]03cef9b2014-04-03 15:58:142983 shader_spec,
2984 &resources,
[email protected]a6739bc2013-09-07 04:45:212985 implementation_type,
2986 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042987 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242988 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382989 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242990 return false;
2991 }
[email protected]87fb6ab2012-06-13 22:28:042992
[email protected]03cef9b2014-04-03 15:58:142993 fragment_translator_ = shader_translator_cache()->GetTranslator(
[email protected]aeecc6b2014-07-03 17:18:262994 GL_FRAGMENT_SHADER,
[email protected]03cef9b2014-04-03 15:58:142995 shader_spec,
2996 &resources,
[email protected]a6739bc2013-09-07 04:45:212997 implementation_type,
2998 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042999 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:243000 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:383001 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:243002 return false;
3003 }
3004 return true;
3005}
3006
[email protected]ae51d192010-04-27 00:48:033007bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:473008 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353009 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033010 return false;
3011 }
3012 }
[email protected]40d90a22013-04-09 03:39:553013 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033014 glGenBuffersARB(n, service_ids.get());
3015 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353016 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033017 }
3018 return true;
3019}
3020
3021bool GLES2DecoderImpl::GenFramebuffersHelper(
3022 GLsizei n, const GLuint* client_ids) {
3023 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353024 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033025 return false;
3026 }
3027 }
[email protected]40d90a22013-04-09 03:39:553028 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033029 glGenFramebuffersEXT(n, service_ids.get());
3030 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353031 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033032 }
3033 return true;
3034}
3035
3036bool GLES2DecoderImpl::GenRenderbuffersHelper(
3037 GLsizei n, const GLuint* client_ids) {
3038 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353039 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033040 return false;
3041 }
3042 }
[email protected]40d90a22013-04-09 03:39:553043 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033044 glGenRenderbuffersEXT(n, service_ids.get());
3045 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353046 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033047 }
3048 return true;
3049}
3050
orglofchcad5a6742014-11-07 19:51:123051bool GLES2DecoderImpl::GenValuebuffersCHROMIUMHelper(GLsizei n,
3052 const GLuint* client_ids) {
3053 for (GLsizei ii = 0; ii < n; ++ii) {
3054 if (GetValuebuffer(client_ids[ii])) {
3055 return false;
3056 }
3057 }
3058 for (GLsizei ii = 0; ii < n; ++ii) {
3059 CreateValuebuffer(client_ids[ii]);
3060 }
3061 return true;
3062}
3063
[email protected]ae51d192010-04-27 00:48:033064bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
3065 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353066 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:033067 return false;
3068 }
3069 }
[email protected]40d90a22013-04-09 03:39:553070 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:033071 glGenTextures(n, service_ids.get());
3072 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353073 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033074 }
3075 return true;
3076}
3077
3078void GLES2DecoderImpl::DeleteBuffersHelper(
3079 GLsizei n, const GLuint* client_ids) {
3080 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:213081 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103082 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:243083 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:113084 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:243085 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:103086 }
[email protected]ed9f9cd2013-02-27 21:12:353087 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033088 }
[email protected]a93bb842010-02-16 23:03:473089 }
[email protected]07f54fcc2009-12-22 02:46:303090}
3091
[email protected]ae51d192010-04-27 00:48:033092void GLES2DecoderImpl::DeleteFramebuffersHelper(
3093 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453094 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153095 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:113096
[email protected]a25fa872010-03-25 02:57:583097 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353098 Framebuffer* framebuffer =
3099 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103100 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:343101 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
3102 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]c986af502013-08-14 01:04:443103 framebuffer_state_.clear_state_dirty = true;
[email protected]ebfb73c2012-08-15 02:37:453104 GLenum target = supports_separate_framebuffer_binds ?
3105 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:113106 glBindFramebufferEXT(target, GetBackbufferServiceId());
3107 }
[email protected]9d3b2e12013-10-02 01:04:343108 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
3109 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:453110 GLenum target = supports_separate_framebuffer_binds ?
3111 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:113112 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:463113 }
[email protected]70d34263c2013-01-09 00:27:453114 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:353115 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033116 }
[email protected]a25fa872010-03-25 02:57:583117 }
[email protected]07f54fcc2009-12-22 02:46:303118}
3119
[email protected]ae51d192010-04-27 00:48:033120void GLES2DecoderImpl::DeleteRenderbuffersHelper(
3121 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453122 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153123 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:583124 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:353125 Renderbuffer* renderbuffer =
3126 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:103127 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:113128 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:243129 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:103130 }
3131 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453132 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343133 if (framebuffer_state_.bound_read_framebuffer.get()) {
3134 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113135 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103136 }
[email protected]9d3b2e12013-10-02 01:04:343137 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3138 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113139 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103140 }
3141 } else {
[email protected]9d3b2e12013-10-02 01:04:343142 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3143 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113144 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:103145 }
3146 }
[email protected]c986af502013-08-14 01:04:443147 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:353148 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033149 }
[email protected]a25fa872010-03-25 02:57:583150 }
[email protected]07f54fcc2009-12-22 02:46:303151}
3152
orglofchcad5a6742014-11-07 19:51:123153void GLES2DecoderImpl::DeleteValuebuffersCHROMIUMHelper(
3154 GLsizei n,
3155 const GLuint* client_ids) {
3156 for (GLsizei ii = 0; ii < n; ++ii) {
3157 Valuebuffer* valuebuffer = GetValuebuffer(client_ids[ii]);
3158 if (valuebuffer) {
3159 if (state_.bound_valuebuffer.get() == valuebuffer) {
3160 state_.bound_valuebuffer = NULL;
3161 }
3162 RemoveValuebuffer(client_ids[ii]);
3163 }
3164 }
3165}
3166
[email protected]ae51d192010-04-27 00:48:033167void GLES2DecoderImpl::DeleteTexturesHelper(
3168 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:453169 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:153170 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:473171 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:493172 TextureRef* texture_ref = GetTexture(client_ids[ii]);
3173 if (texture_ref) {
3174 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:103175 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:443176 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463177 }
[email protected]370eaf12013-05-18 09:19:493178 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:023179 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:493180 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103181 }
3182 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:453183 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:343184 if (framebuffer_state_.bound_read_framebuffer.get()) {
3185 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113186 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103187 }
[email protected]9d3b2e12013-10-02 01:04:343188 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3189 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113190 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103191 }
3192 } else {
[email protected]9d3b2e12013-10-02 01:04:343193 if (framebuffer_state_.bound_draw_framebuffer.get()) {
3194 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:113195 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:103196 }
3197 }
[email protected]e51bdf32011-11-23 22:21:463198#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:073199 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:463200 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
3201 ReleaseIOSurfaceForTexture(service_id);
3202 }
3203#endif
[email protected]ed9f9cd2013-02-27 21:12:353204 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:033205 }
[email protected]a93bb842010-02-16 23:03:473206 }
[email protected]07f54fcc2009-12-22 02:46:303207}
3208
[email protected]43f28f832010-02-03 02:28:483209// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:323210
[email protected]eb54a562010-01-20 21:55:183211bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:343212 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:383213 return false;
3214
[email protected]177d1342013-12-07 04:20:343215 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:433216 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:293217
jbauman7a059312014-10-16 19:30:543218 MaybeExitOnContextLost();
[email protected]e9f0ca82013-04-01 23:52:293219
[email protected]63c9b052012-05-17 18:27:383220 return false;
[email protected]38d139d2011-07-14 00:38:433221 }
3222
[email protected]69a8701e2013-03-07 21:31:093223 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:093224
[email protected]9b753992013-04-27 02:04:413225 // Rebind the FBO if it was unbound by the context.
3226 if (workarounds().unbind_fbo_on_context_switch)
3227 RestoreFramebufferBindings();
3228
[email protected]c986af502013-08-14 01:04:443229 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:493230
[email protected]69a8701e2013-03-07 21:31:093231 return true;
3232}
3233
3234void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:553235 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:323236 if (engine() && query_manager_.get())
3237 query_manager_->ProcessPendingTransferQueries();
3238
[email protected]5b3a8e02013-03-13 05:36:443239 // TODO(epenner): Is there a better place to do this?
3240 // This needs to occur before we execute any batch of commands
3241 // from the client, as the client may have recieved an async
3242 // completion while issuing those commands.
3243 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:483244 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:183245}
3246
[email protected]8e3e0662010-08-23 18:46:303247static void RebindCurrentFramebuffer(
3248 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:063249 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:243250 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:063251 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:463252
[email protected]a3783712012-01-20 22:18:243253 if (framebuffer_id == 0) {
3254 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:303255 }
[email protected]297ca1c2011-06-20 23:08:463256
[email protected]8e3e0662010-08-23 18:46:303257 glBindFramebufferEXT(target, framebuffer_id);
3258}
3259
3260void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:443261 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463262
[email protected]62e155e2012-10-23 22:43:153263 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:303264 RebindCurrentFramebuffer(
3265 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:343266 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243267 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303268 } else {
3269 RebindCurrentFramebuffer(
3270 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343271 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243272 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303273 RebindCurrentFramebuffer(
3274 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:343275 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:243276 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:303277 }
[email protected]70d34263c2013-01-09 00:27:453278 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:303279}
3280
[email protected]0d6bfdc2011-11-02 01:32:203281bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:353282 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:203283 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:103284 if (!framebuffer) {
achaulkcf5316f2014-09-26 19:28:423285 if (surfaceless_)
3286 return false;
[email protected]60f22d32012-12-12 00:31:583287 if (backbuffer_needs_clear_bits_) {
3288 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323289 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453290 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]60f22d32012-12-12 00:31:583291 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473292 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3293 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]60f22d32012-12-12 00:31:583294 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:453295 state_.SetDeviceDepthMask(GL_TRUE);
3296 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]ee757922014-06-06 05:21:423297 bool reset_draw_buffer = false;
brucedawson18249152014-10-31 23:02:323298 if ((backbuffer_needs_clear_bits_ & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]ee757922014-06-06 05:21:423299 group_->draw_buffer() == GL_NONE) {
3300 reset_draw_buffer = true;
3301 GLenum buf = GL_BACK;
3302 if (GetBackbufferServiceId() != 0) // emulated backbuffer
3303 buf = GL_COLOR_ATTACHMENT0;
3304 glDrawBuffersARB(1, &buf);
3305 }
[email protected]60f22d32012-12-12 00:31:583306 glClear(backbuffer_needs_clear_bits_);
[email protected]ee757922014-06-06 05:21:423307 if (reset_draw_buffer) {
3308 GLenum buf = GL_NONE;
3309 glDrawBuffersARB(1, &buf);
3310 }
[email protected]60f22d32012-12-12 00:31:583311 backbuffer_needs_clear_bits_ = 0;
3312 RestoreClearState();
3313 }
[email protected]0d6bfdc2011-11-02 01:32:203314 return true;
3315 }
3316
[email protected]968351b2011-12-20 08:26:513317 if (framebuffer_manager()->IsComplete(framebuffer)) {
3318 return true;
3319 }
3320
[email protected]0d6bfdc2011-11-02 01:32:203321 GLenum completeness = framebuffer->IsPossiblyComplete();
3322 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513323 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433324 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:273325 return false;
3326 }
[email protected]0d6bfdc2011-11-02 01:32:203327
3328 // Are all the attachments cleared?
3329 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
3330 texture_manager()->HaveUnclearedMips()) {
3331 if (!framebuffer->IsCleared()) {
3332 // Can we clear them?
[email protected]73276522012-11-09 05:50:203333 if (framebuffer->GetStatus(texture_manager(), target) !=
3334 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513335 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433336 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3337 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:203338 return false;
3339 }
3340 ClearUnclearedAttachments(target, framebuffer);
3341 }
3342 }
3343
[email protected]968351b2011-12-20 08:26:513344 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203345 if (framebuffer->GetStatus(texture_manager(), target) !=
3346 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513347 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433348 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3349 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513350 return false;
3351 }
3352 framebuffer_manager()->MarkAsComplete(framebuffer);
3353 }
3354
[email protected]0d6bfdc2011-11-02 01:32:203355 // NOTE: At this point we don't know if the framebuffer is complete but
3356 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273357 return true;
3358}
3359
[email protected]0d6bfdc2011-11-02 01:32:203360bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153361 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513362 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343363 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3364 func_name);
[email protected]28718a92013-04-04 12:12:513365
3366 if (valid)
3367 OnUseFramebuffer();
3368
3369 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203370 }
[email protected]9d3b2e12013-10-02 01:04:343371 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113372 GL_DRAW_FRAMEBUFFER_EXT,
3373 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343374 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113375 GL_READ_FRAMEBUFFER_EXT,
3376 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203377}
3378
[email protected]2ea5950d2014-07-09 18:20:343379bool GLES2DecoderImpl::CheckBoundReadFramebufferColorAttachment(
3380 const char* func_name) {
3381 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3382 framebuffer_state_.bound_read_framebuffer.get() :
3383 framebuffer_state_.bound_draw_framebuffer.get();
3384 if (!framebuffer)
3385 return true;
3386 if (framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0) == NULL) {
3387 LOCAL_SET_GL_ERROR(
3388 GL_INVALID_OPERATION, func_name, "no color image attached");
3389 return false;
3390 }
3391 return true;
3392}
3393
zmo383512cf2014-10-14 00:11:003394bool GLES2DecoderImpl::FormsTextureCopyingFeedbackLoop(
3395 TextureRef* texture, GLint level) {
3396 Framebuffer* framebuffer = features().chromium_framebuffer_multisample ?
3397 framebuffer_state_.bound_read_framebuffer.get() :
3398 framebuffer_state_.bound_draw_framebuffer.get();
3399 if (!framebuffer)
3400 return false;
3401 const Framebuffer::Attachment* attachment = framebuffer->GetAttachment(
3402 GL_COLOR_ATTACHMENT0);
3403 if (!attachment)
3404 return false;
3405 return attachment->FormsFeedbackLoop(texture, level);
3406}
3407
[email protected]8e3e0662010-08-23 18:46:303408gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353409 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453410 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203411 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353412 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203413 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263414 if (attachment) {
3415 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503416 }
[email protected]9edc6b22010-12-23 02:00:263417 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023418 } else if (offscreen_target_frame_buffer_.get()) {
3419 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353420 } else {
[email protected]f62a5ab2011-05-23 20:34:153421 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023422 }
[email protected]246a70452010-03-05 21:53:503423}
3424
[email protected]68586372013-12-11 01:27:593425GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3426 Framebuffer* framebuffer =
3427 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3428 if (framebuffer != NULL) {
3429 return framebuffer->GetColorAttachmentTextureType();
3430 } else {
3431 return GL_UNSIGNED_BYTE;
3432 }
3433}
3434
[email protected]9edc6b22010-12-23 02:00:263435GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353436 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453437 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203438 if (framebuffer != NULL) {
3439 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463440 } else if (offscreen_target_frame_buffer_.get()) {
3441 return offscreen_target_color_format_;
3442 } else {
3443 return back_buffer_color_format_;
3444 }
3445}
3446
3447GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353448 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453449 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203450 if (framebuffer != NULL) {
3451 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263452 } else if (offscreen_target_frame_buffer_.get()) {
3453 return offscreen_target_color_format_;
3454 } else {
[email protected]32fe9aa2011-01-21 23:47:133455 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263456 }
3457}
3458
[email protected]9a5afa432011-07-22 18:16:393459void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513460 if (!offscreen_saved_color_texture_info_.get())
3461 return;
3462 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3463 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3464 texture_manager()->SetLevelInfo(
3465 offscreen_saved_color_texture_info_.get(),
3466 GL_TEXTURE_2D,
3467 0, // level
3468 GL_RGBA,
3469 offscreen_size_.width(),
3470 offscreen_size_.height(),
3471 1, // depth
3472 0, // border
3473 GL_RGBA,
3474 GL_UNSIGNED_BYTE,
3475 true);
[email protected]737191ee72014-03-09 08:02:423476 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513477 "UpdateParentTextureInfo",
3478 GetErrorState(),
3479 offscreen_saved_color_texture_info_.get(),
3480 GL_TEXTURE_MAG_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263481 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423482 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513483 "UpdateParentTextureInfo",
3484 GetErrorState(),
3485 offscreen_saved_color_texture_info_.get(),
3486 GL_TEXTURE_MIN_FILTER,
[email protected]eeeb07b92014-08-16 07:46:263487 GL_LINEAR);
[email protected]737191ee72014-03-09 08:02:423488 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513489 "UpdateParentTextureInfo",
3490 GetErrorState(),
3491 offscreen_saved_color_texture_info_.get(),
3492 GL_TEXTURE_WRAP_S,
3493 GL_CLAMP_TO_EDGE);
[email protected]737191ee72014-03-09 08:02:423494 texture_manager()->SetParameteri(
[email protected]2ad674132013-06-05 07:48:513495 "UpdateParentTextureInfo",
3496 GetErrorState(),
3497 offscreen_saved_color_texture_info_.get(),
3498 GL_TEXTURE_WRAP_T,
3499 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443500 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3501 &state_, target);
[email protected]2ad674132013-06-05 07:48:513502 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353503}
3504
[email protected]799b4b22011-08-22 17:09:593505void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073506 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523507 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003508}
3509
[email protected]1d82e822013-04-10 21:32:323510Logger* GLES2DecoderImpl::GetLogger() {
3511 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523512}
3513
[email protected]cac16542014-01-15 17:53:513514void GLES2DecoderImpl::BeginDecoding() {
3515 gpu_tracer_->BeginDecoding();
dyencb86f2f2014-12-09 18:35:413516 gpu_trace_commands_ = gpu_tracer_->IsTracing() && *gpu_decoder_category_;
vmiura1c2b1de2014-09-19 19:03:243517 gpu_debug_commands_ = log_commands() || debug() || gpu_trace_commands_ ||
3518 (*cb_command_trace_category_ != 0);
[email protected]cac16542014-01-15 17:53:513519}
3520
3521void GLES2DecoderImpl::EndDecoding() {
3522 gpu_tracer_->EndDecoding();
3523}
3524
[email protected]d3eba342013-04-18 21:11:503525ErrorState* GLES2DecoderImpl::GetErrorState() {
3526 return state_.GetErrorState();
3527}
3528
[email protected]e3932abb2013-03-13 00:01:373529void GLES2DecoderImpl::SetShaderCacheCallback(
3530 const ShaderCacheCallback& callback) {
3531 shader_cache_callback_ = callback;
3532}
3533
[email protected]840a7e462013-02-27 01:29:513534void GLES2DecoderImpl::SetWaitSyncPointCallback(
3535 const WaitSyncPointCallback& callback) {
3536 wait_sync_point_callback_ = callback;
3537}
3538
[email protected]85a4ac22013-05-31 01:58:473539AsyncPixelTransferManager*
3540 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3541 return async_pixel_transfer_manager_.get();
3542}
3543
3544void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3545 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593546}
3547
[email protected]498b5c072013-06-04 19:30:073548void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3549 AsyncPixelTransferManager* manager) {
3550 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3551}
3552
[email protected]1318e922010-09-17 22:03:163553bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3554 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493555 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3556 if (texture_ref) {
3557 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163558 return true;
3559 }
3560 return false;
3561}
3562
[email protected]63b465922012-09-06 02:04:523563uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443564 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483565 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523566}
3567
3568base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443569 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483570 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523571}
3572
3573base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3574 return total_processing_commands_time_;
3575}
3576
[email protected]dc25dda2012-09-27 21:36:303577void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3578 total_processing_commands_time_ += time;
3579}
3580
[email protected]63c9b052012-05-17 18:27:383581void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063582 if (!initialized())
3583 return;
3584
[email protected]63c9b052012-05-17 18:27:383585 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053586
[email protected]80eb6b52012-01-19 00:14:413587 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243588 state_.vertex_attrib_manager = NULL;
[email protected]81f20a622014-04-18 01:54:523589 state_.default_vertex_attrib_manager = NULL;
[email protected]1868a342012-11-07 15:56:023590 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243591 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133592 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343593 framebuffer_state_.bound_read_framebuffer = NULL;
3594 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243595 state_.bound_renderbuffer = NULL;
orglofchcad5a6742014-11-07 19:51:123596 state_.bound_valuebuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413597
[email protected]cadac622013-06-11 16:46:363598 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513599 DCHECK(offscreen_target_color_texture_);
3600 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3601 offscreen_saved_color_texture_->id());
3602 offscreen_saved_color_texture_->Invalidate();
3603 offscreen_saved_color_texture_info_ = NULL;
3604 }
[email protected]eadc96792010-10-27 19:39:393605 if (have_context) {
[email protected]c322e882012-05-23 18:06:183606 if (copy_texture_CHROMIUM_.get()) {
3607 copy_texture_CHROMIUM_->Destroy();
3608 copy_texture_CHROMIUM_.reset();
3609 }
[email protected]43410e92012-04-20 17:06:283610
sievers2384f2b2014-11-18 02:10:353611 clear_framebuffer_blit_.reset();
3612
[email protected]7cd76fd2013-06-02 21:11:113613 if (state_.current_program.get()) {
3614 program_manager()->UnuseProgram(shader_manager(),
3615 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143616 }
3617
[email protected]b1122982010-05-17 23:04:243618 if (attrib_0_buffer_id_) {
3619 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3620 }
[email protected]8fbedc02010-11-18 18:43:403621 if (fixed_attrib_buffer_id_) {
3622 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3623 }
[email protected]b1122982010-05-17 23:04:243624
[email protected]4a4c18b2013-09-13 22:50:103625 if (validation_texture_) {
3626 glDeleteTextures(1, &validation_texture_);
3627 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3628 glDeleteFramebuffersEXT(1, &validation_fbo_);
3629 }
3630
[email protected]97872062010-11-03 19:07:053631 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543632 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053633 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543634 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053635 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023636 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053637 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153638 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053639 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153640 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053641 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023642 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053643 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543644 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273645 if (offscreen_resolved_frame_buffer_.get())
3646 offscreen_resolved_frame_buffer_->Destroy();
3647 if (offscreen_resolved_color_texture_.get())
3648 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053649 } else {
3650 if (offscreen_target_frame_buffer_.get())
3651 offscreen_target_frame_buffer_->Invalidate();
3652 if (offscreen_target_color_texture_.get())
3653 offscreen_target_color_texture_->Invalidate();
3654 if (offscreen_target_color_render_buffer_.get())
3655 offscreen_target_color_render_buffer_->Invalidate();
3656 if (offscreen_target_depth_render_buffer_.get())
3657 offscreen_target_depth_render_buffer_->Invalidate();
3658 if (offscreen_target_stencil_render_buffer_.get())
3659 offscreen_target_stencil_render_buffer_->Invalidate();
3660 if (offscreen_saved_frame_buffer_.get())
3661 offscreen_saved_frame_buffer_->Invalidate();
3662 if (offscreen_saved_color_texture_.get())
3663 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273664 if (offscreen_resolved_frame_buffer_.get())
3665 offscreen_resolved_frame_buffer_->Invalidate();
3666 if (offscreen_resolved_color_texture_.get())
3667 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023668 }
[email protected]83a52d032013-07-24 10:30:373669
3670 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3671 // Otherwise, we can leak objects. http://crbug.com/258772.
3672 // state_.current_program must be reset before group_ is reset because
3673 // the later deletes the ProgramManager object that referred by
3674 // state_.current_program object.
3675 state_.current_program = NULL;
3676
[email protected]43410e92012-04-20 17:06:283677 copy_texture_CHROMIUM_.reset();
sievers2384f2b2014-11-18 02:10:353678 clear_framebuffer_blit_.reset();
[email protected]97872062010-11-03 19:07:053679
[email protected]882ba1e22012-03-08 19:02:533680 if (query_manager_.get()) {
3681 query_manager_->Destroy(have_context);
3682 query_manager_.reset();
3683 }
3684
[email protected]944b62f32012-09-27 02:20:463685 if (vertex_array_manager_ .get()) {
3686 vertex_array_manager_->Destroy(have_context);
3687 vertex_array_manager_.reset();
3688 }
3689
[email protected]d2eaf52f2014-07-31 15:01:243690 if (image_manager_.get()) {
3691 image_manager_->Destroy(have_context);
3692 image_manager_.reset();
3693 }
3694
[email protected]97872062010-11-03 19:07:053695 offscreen_target_frame_buffer_.reset();
3696 offscreen_target_color_texture_.reset();
3697 offscreen_target_color_render_buffer_.reset();
3698 offscreen_target_depth_render_buffer_.reset();
3699 offscreen_target_stencil_render_buffer_.reset();
3700 offscreen_saved_frame_buffer_.reset();
3701 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273702 offscreen_resolved_frame_buffer_.reset();
3703 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463704
[email protected]03cef9b2014-04-03 15:58:143705 // Need to release these before releasing |group_| which may own the
3706 // ShaderTranslatorCache.
3707 fragment_translator_ = NULL;
3708 vertex_translator_ = NULL;
3709
[email protected]85a4ac22013-05-31 01:58:473710 // Should destroy the transfer manager before the texture manager held
3711 // by the context group.
3712 async_pixel_transfer_manager_.reset();
3713
[email protected]7cd76fd2013-06-02 21:11:113714 if (group_.get()) {
[email protected]ac5e4022014-01-24 12:44:393715 framebuffer_manager()->RemoveObserver(this);
[email protected]2d9d3b92013-01-18 01:07:233716 group_->Destroy(this, have_context);
3717 group_ = NULL;
3718 }
3719
3720 if (context_.get()) {
3721 context_->ReleaseCurrent(NULL);
3722 context_ = NULL;
3723 }
3724
[email protected]e51bdf32011-11-23 22:21:463725#if defined(OS_MACOSX)
3726 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3727 it != texture_to_io_surface_map_.end(); ++it) {
3728 CFRelease(it->second);
3729 }
3730 texture_to_io_surface_map_.clear();
3731#endif
[email protected]96449d2c2009-11-25 00:01:323732}
3733
[email protected]63c9b052012-05-17 18:27:383734void GLES2DecoderImpl::SetSurface(
3735 const scoped_refptr<gfx::GLSurface>& surface) {
3736 DCHECK(context_->IsCurrent(NULL));
3737 DCHECK(surface_.get());
3738 surface_ = surface;
3739 RestoreCurrentFramebufferBindings();
3740}
3741
[email protected]aba551b2014-02-08 03:38:323742void GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
3743 if (!offscreen_saved_color_texture_.get()) {
3744 LOG(ERROR) << "Called ProduceFrontBuffer on a non-offscreen context";
3745 return;
3746 }
[email protected]2ad674132013-06-05 07:48:513747 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243748 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073749 offscreen_saved_color_texture_info_ = TextureRef::Create(
3750 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513751 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3752 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393753 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243754 }
[email protected]aba551b2014-02-08 03:38:323755 mailbox_manager()->ProduceTexture(
sievers8b373ec52014-10-24 23:04:063756 mailbox, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243757}
3758
[email protected]799b4b22011-08-22 17:09:593759bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3760 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3761 if (!is_offscreen) {
3762 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3763 << " with an onscreen framebuffer.";
3764 return false;
3765 }
3766
3767 if (offscreen_size_ == size)
3768 return true;
3769
3770 offscreen_size_ = size;
3771 int w = offscreen_size_.width();
3772 int h = offscreen_size_.height();
3773 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3774 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3775 << "to allocate storage due to excessive dimensions.";
3776 return false;
3777 }
3778
3779 // Reallocate the offscreen target buffers.
3780 DCHECK(offscreen_target_color_format_);
3781 if (IsOffscreenBufferMultisampled()) {
3782 if (!offscreen_target_color_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253783 feature_info_.get(),
3784 offscreen_size_,
3785 offscreen_target_color_format_,
3786 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593787 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3788 << "to allocate storage for offscreen target color buffer.";
3789 return false;
3790 }
3791 } else {
3792 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093793 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593794 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3795 << "to allocate storage for offscreen target color texture.";
3796 return false;
3797 }
3798 }
3799 if (offscreen_target_depth_format_ &&
3800 !offscreen_target_depth_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253801 feature_info_.get(),
3802 offscreen_size_,
3803 offscreen_target_depth_format_,
3804 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593805 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3806 << "to allocate storage for offscreen target depth buffer.";
3807 return false;
3808 }
3809 if (offscreen_target_stencil_format_ &&
3810 !offscreen_target_stencil_render_buffer_->AllocateStorage(
Daniel Cheng3d7ce9f2014-08-26 00:26:253811 feature_info_.get(),
3812 offscreen_size_,
3813 offscreen_target_stencil_format_,
3814 offscreen_target_samples_)) {
[email protected]799b4b22011-08-22 17:09:593815 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3816 << "to allocate storage for offscreen target stencil buffer.";
3817 return false;
3818 }
3819
3820 // Attach the offscreen target buffers to the target frame buffer.
3821 if (IsOffscreenBufferMultisampled()) {
3822 offscreen_target_frame_buffer_->AttachRenderBuffer(
3823 GL_COLOR_ATTACHMENT0,
3824 offscreen_target_color_render_buffer_.get());
3825 } else {
3826 offscreen_target_frame_buffer_->AttachRenderTexture(
3827 offscreen_target_color_texture_.get());
3828 }
3829 if (offscreen_target_depth_format_) {
3830 offscreen_target_frame_buffer_->AttachRenderBuffer(
3831 GL_DEPTH_ATTACHMENT,
3832 offscreen_target_depth_render_buffer_.get());
3833 }
3834 const bool packed_depth_stencil =
3835 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3836 if (packed_depth_stencil) {
3837 offscreen_target_frame_buffer_->AttachRenderBuffer(
3838 GL_STENCIL_ATTACHMENT,
3839 offscreen_target_depth_render_buffer_.get());
3840 } else if (offscreen_target_stencil_format_) {
3841 offscreen_target_frame_buffer_->AttachRenderBuffer(
3842 GL_STENCIL_ATTACHMENT,
3843 offscreen_target_stencil_render_buffer_.get());
3844 }
3845
3846 if (offscreen_target_frame_buffer_->CheckStatus() !=
3847 GL_FRAMEBUFFER_COMPLETE) {
3848 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3849 << "because offscreen FBO was incomplete.";
3850 return false;
3851 }
3852
3853 // Clear the target frame buffer.
3854 {
3855 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3856 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
pkasting45796dc2014-10-17 04:18:323857 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1.f);
[email protected]454157e2014-05-03 02:49:453858 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]799b4b22011-08-22 17:09:593859 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:473860 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
3861 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]799b4b22011-08-22 17:09:593862 glClearDepth(0);
[email protected]454157e2014-05-03 02:49:453863 state_.SetDeviceDepthMask(GL_TRUE);
3864 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]799b4b22011-08-22 17:09:593865 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3866 RestoreClearState();
3867 }
[email protected]d85ef76d2011-09-08 22:21:433868
3869 // Destroy the offscreen resolved framebuffers.
3870 if (offscreen_resolved_frame_buffer_.get())
3871 offscreen_resolved_frame_buffer_->Destroy();
3872 if (offscreen_resolved_color_texture_.get())
3873 offscreen_resolved_color_texture_->Destroy();
3874 offscreen_resolved_color_texture_.reset();
3875 offscreen_resolved_frame_buffer_.reset();
3876
[email protected]799b4b22011-08-22 17:09:593877 return true;
[email protected]6217d392010-03-25 22:08:353878}
3879
vmiuracd108592014-09-08 14:36:343880error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size,
3881 const void* cmd_data) {
3882 const gles2::cmds::ResizeCHROMIUM& c =
3883 *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data);
[email protected]09e17272012-11-30 10:30:443884 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023885 return error::kDeferCommandUntilLater;
3886
[email protected]799b4b22011-08-22 17:09:593887 GLuint width = static_cast<GLuint>(c.width);
3888 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073889 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593890 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413891
3892 width = std::max(1U, width);
3893 height = std::max(1U, height);
3894
[email protected]a0d989162011-11-22 13:15:073895#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3896 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003897 // Make sure that we are done drawing to the back buffer before resizing.
3898 glFinish();
3899#endif
[email protected]799b4b22011-08-22 17:09:593900 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3901 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493902 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3903 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3904 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593905 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493906 }
[email protected]7ff86b92010-11-25 17:50:003907 }
[email protected]799b4b22011-08-22 17:09:593908
[email protected]9d37f062011-11-22 01:24:523909 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073910 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443911 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493912 if (!context_->IsCurrent(surface_.get())) {
3913 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3914 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053915 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493916 }
[email protected]658f7562011-09-09 05:24:053917 }
[email protected]799b4b22011-08-22 17:09:593918
3919 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393920}
3921
[email protected]96449d2c2009-11-25 00:01:323922const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3923 if (command_id > kStartPoint && command_id < kNumCommands) {
3924 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3925 }
3926 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3927}
3928
vmiura8266ca72014-09-09 21:37:003929// Decode a command, and call the corresponding GL functions.
3930// NOTE: DoCommand() is slower than calling DoCommands() on larger batches
3931// of commands at once, and is now only used for tests that need to track
3932// individual commands.
3933error::Error GLES2DecoderImpl::DoCommand(unsigned int command,
3934 unsigned int arg_count,
3935 const void* cmd_data) {
3936 return DoCommands(1, cmd_data, arg_count + 1, 0);
3937}
3938
3939// Decode multiple commands, and call the corresponding GL functions.
3940// NOTE: 'buffer' is a pointer to the command buffer. As such, it could be
3941// changed by a (malicious) client at any time, so if validation has to happen,
3942// it should operate on a copy of them.
3943// NOTE: This is duplicating code from AsyncAPIInterface::DoCommands() in the
3944// interest of performance in this critical execution loop.
vmiura1c2b1de2014-09-19 19:03:243945template <bool DebugImpl>
3946error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
3947 const void* buffer,
3948 int num_entries,
3949 int* entries_processed) {
vmiura8266ca72014-09-09 21:37:003950 commands_to_process_ = num_commands;
[email protected]f7a64ee2010-02-01 22:24:143951 error::Error result = error::kNoError;
vmiura8266ca72014-09-09 21:37:003952 const CommandBufferEntry* cmd_data =
3953 static_cast<const CommandBufferEntry*>(buffer);
3954 int process_pos = 0;
3955 unsigned int command = 0;
3956
3957 while (process_pos < num_entries && result == error::kNoError &&
3958 commands_to_process_--) {
3959 const unsigned int size = cmd_data->value_header.size;
3960 command = cmd_data->value_header.command;
3961
3962 if (size == 0) {
3963 result = error::kInvalidSize;
3964 break;
3965 }
3966
3967 if (static_cast<int>(size) + process_pos > num_entries) {
3968 result = error::kOutOfBounds;
3969 break;
3970 }
3971
vmiura1c2b1de2014-09-19 19:03:243972 if (DebugImpl) {
3973 TRACE_EVENT_BEGIN0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
3974 GetCommandName(command));
vmiura8266ca72014-09-09 21:37:003975
vmiura1c2b1de2014-09-19 19:03:243976 if (log_commands()) {
3977 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
3978 << "cmd: " << GetCommandName(command);
3979 }
vmiura8266ca72014-09-09 21:37:003980 }
3981
3982 const unsigned int arg_count = size - 1;
3983 unsigned int command_index = command - kStartPoint - 1;
3984 if (command_index < arraysize(command_info)) {
3985 const CommandInfo& info = command_info[command_index];
3986 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3987 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3988 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
3989 bool doing_gpu_trace = false;
vmiura1c2b1de2014-09-19 19:03:243990 if (DebugImpl && gpu_trace_commands_) {
vmiura8266ca72014-09-09 21:37:003991 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
3992 doing_gpu_trace = true;
dyencb86f2f2014-12-09 18:35:413993 gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_decoder"),
3994 GetCommandName(command),
3995 kTraceDecoder);
vmiura8266ca72014-09-09 21:37:003996 }
[email protected]cac16542014-01-15 17:53:513997 }
[email protected]cac16542014-01-15 17:53:513998
vmiura8266ca72014-09-09 21:37:003999 uint32 immediate_data_size = (arg_count - info_arg_count) *
4000 sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:324001
vmiura8266ca72014-09-09 21:37:004002 result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
[email protected]cac16542014-01-15 17:53:514003
vmiura1c2b1de2014-09-19 19:03:244004 if (DebugImpl && doing_gpu_trace)
vmiura8266ca72014-09-09 21:37:004005 gpu_tracer_->End(kTraceDecoder);
[email protected]cac16542014-01-15 17:53:514006
vmiura1c2b1de2014-09-19 19:03:244007 if (DebugImpl && debug()) {
vmiura8266ca72014-09-09 21:37:004008 GLenum error;
4009 while ((error = glGetError()) != GL_NO_ERROR) {
4010 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
4011 << "GL ERROR: " << GLES2Util::GetStringEnum(error)
4012 << " : " << GetCommandName(command);
4013 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
4014 }
[email protected]b9849abf2009-11-25 19:13:194015 }
vmiura8266ca72014-09-09 21:37:004016 } else {
4017 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:324018 }
4019 } else {
vmiura8266ca72014-09-09 21:37:004020 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:324021 }
vmiura1c2b1de2014-09-19 19:03:244022
4023 if (DebugImpl) {
4024 TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cb_command"),
4025 GetCommandName(command));
4026 }
4027
vmiura8266ca72014-09-09 21:37:004028 if (result == error::kNoError &&
4029 current_decoder_error_ != error::kNoError) {
[email protected]a3a93e7b2010-08-28 00:48:564030 result = current_decoder_error_;
4031 current_decoder_error_ = error::kNoError;
vmiura8266ca72014-09-09 21:37:004032 }
4033
4034 if (result != error::kDeferCommandUntilLater) {
4035 process_pos += size;
4036 cmd_data += size;
4037 }
[email protected]a3a93e7b2010-08-28 00:48:564038 }
vmiura8266ca72014-09-09 21:37:004039
4040 if (entries_processed)
4041 *entries_processed = process_pos;
4042
4043 if (error::IsError(result)) {
4044 LOG(ERROR) << "Error: " << result << " for Command "
4045 << GetCommandName(command);
4046 }
4047
[email protected]b9849abf2009-11-25 19:13:194048 return result;
[email protected]96449d2c2009-11-25 00:01:324049}
4050
vmiura1c2b1de2014-09-19 19:03:244051error::Error GLES2DecoderImpl::DoCommands(unsigned int num_commands,
4052 const void* buffer,
4053 int num_entries,
4054 int* entries_processed) {
4055 if (gpu_debug_commands_) {
4056 return DoCommandsImpl<true>(
4057 num_commands, buffer, num_entries, entries_processed);
4058 } else {
4059 return DoCommandsImpl<false>(
4060 num_commands, buffer, num_entries, entries_processed);
4061 }
4062}
4063
[email protected]ed9f9cd2013-02-27 21:12:354064void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
4065 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:504066}
4067
[email protected]882ba1e22012-03-08 19:02:534068void GLES2DecoderImpl::DoFinish() {
4069 glFinish();
[email protected]5a36dc132013-07-23 23:17:554070 ProcessPendingReadPixels();
revemancc241eb2014-11-11 03:30:374071 ProcessPendingQueries(true);
[email protected]882ba1e22012-03-08 19:02:534072}
4073
4074void GLES2DecoderImpl::DoFlush() {
4075 glFlush();
revemancc241eb2014-11-11 03:30:374076 ProcessPendingQueries(false);
[email protected]882ba1e22012-03-08 19:02:534077}
4078
[email protected]3916c97e2010-02-25 03:20:504079void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:454080 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:024081 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:514082 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:534083 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:504084 return;
4085 }
[email protected]e259eb412012-10-13 05:47:244086 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:454087 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:504088}
4089
[email protected]051b1372010-04-12 02:42:084090void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:074091 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:084092 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034093 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:074094 buffer = GetBuffer(client_id);
4095 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:354096 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224097 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4098 "glBindBuffer",
4099 "id not generated by glGenBuffers");
[email protected]bf5a8d132011-08-16 08:39:354100 return;
4101 }
4102
[email protected]b10492f2013-03-08 05:24:074103 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:034104 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354105 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:074106 buffer = GetBuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034107 }
[email protected]051b1372010-04-12 02:42:084108 }
[email protected]b10492f2013-03-08 05:24:074109 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
4110 if (buffer) {
4111 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:514112 LOCAL_SET_GL_ERROR(
4113 GL_INVALID_OPERATION,
4114 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:474115 return;
4116 }
[email protected]b10492f2013-03-08 05:24:074117 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:474118 }
[email protected]96449d2c2009-11-25 00:01:324119 switch (target) {
4120 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:074121 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:324122 break;
4123 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:074124 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:324125 break;
4126 default:
[email protected]a93bb842010-02-16 23:03:474127 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:324128 break;
4129 }
[email protected]051b1372010-04-12 02:42:084130 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:324131}
4132
[email protected]f3b191b2013-06-19 03:43:544133bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
4134 bool all_draw_buffers) {
4135 Framebuffer* framebuffer =
4136 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
4137 if (!all_draw_buffers || !framebuffer) {
4138 return (GLES2Util::GetChannelsForFormat(
4139 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
4140 }
4141 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:464142}
4143
4144bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354145 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454146 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204147 if (framebuffer) {
4148 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:464149 }
4150 if (offscreen_target_frame_buffer_.get()) {
4151 return offscreen_target_depth_format_ != 0;
4152 }
4153 return back_buffer_has_depth_;
4154}
4155
4156bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:354157 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454158 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204159 if (framebuffer) {
4160 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:464161 }
4162 if (offscreen_target_frame_buffer_.get()) {
4163 return offscreen_target_stencil_format_ != 0 ||
4164 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
4165 }
4166 return back_buffer_has_stencil_;
4167}
4168
4169void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:444170 if (framebuffer_state_.clear_state_dirty) {
[email protected]454157e2014-05-03 02:49:454171 bool have_alpha = BoundFramebufferHasColorAttachmentWithAlpha(true);
4172 state_.SetDeviceColorMask(state_.color_mask_red,
4173 state_.color_mask_green,
4174 state_.color_mask_blue,
4175 state_.color_mask_alpha && have_alpha);
4176
[email protected]297ca1c2011-06-20 23:08:464177 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]454157e2014-05-03 02:49:454178 state_.SetDeviceDepthMask(state_.depth_mask && have_depth);
4179
[email protected]297ca1c2011-06-20 23:08:464180 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]454157e2014-05-03 02:49:454181 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424182 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]454157e2014-05-03 02:49:454183 state_.SetDeviceStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:424184 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]454157e2014-05-03 02:49:454185
4186 state_.SetDeviceCapabilityState(
4187 GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
4188 state_.SetDeviceCapabilityState(
[email protected]f731b9462012-10-30 00:35:224189 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
[email protected]c986af502013-08-14 01:04:444190 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:464191 }
4192}
4193
[email protected]1868a342012-11-07 15:56:024194GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:114195 return (offscreen_target_frame_buffer_.get())
4196 ? offscreen_target_frame_buffer_->id()
4197 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:024198}
4199
[email protected]8875a5f2014-06-27 08:33:474200void GLES2DecoderImpl::RestoreState(const ContextState* prev_state) {
[email protected]962bfbe72013-05-24 11:16:144201 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
4202 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:064203 // Restore the Framebuffer first because of bugs in Intel drivers.
4204 // Intel drivers incorrectly clip the viewport settings to
4205 // the size of the current framebuffer object.
4206 RestoreFramebufferBindings();
[email protected]5baa86bc2014-01-16 04:33:164207 state_.RestoreState(prev_state);
[email protected]29a4d902013-02-26 20:18:064208}
4209
4210void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:344211 GLuint service_id =
4212 framebuffer_state_.bound_draw_framebuffer.get()
4213 ? framebuffer_state_.bound_draw_framebuffer->service_id()
4214 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064215 if (!features().chromium_framebuffer_multisample) {
4216 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
4217 } else {
4218 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:344219 service_id = framebuffer_state_.bound_read_framebuffer.get()
4220 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:114221 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:064222 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
4223 }
[email protected]70d34263c2013-01-09 00:27:454224 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:064225}
4226
[email protected]8875a5f2014-06-27 08:33:474227void GLES2DecoderImpl::RestoreRenderbufferBindings() {
4228 state_.RestoreRenderbufferBindings();
4229}
4230
[email protected]29a4d902013-02-26 20:18:064231void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:104232 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
4233 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:254234 GLenum target = texture->target();
4235 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:064236 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254237 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:064238 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254239 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:064240 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254241 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:064242 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:254243 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:064244 RestoreTextureUnitBindings(state_.active_texture_unit);
4245 }
[email protected]70d34263c2013-01-09 00:27:454246}
4247
[email protected]cd2ef752014-02-12 23:16:034248void GLES2DecoderImpl::ClearAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524249 // Must use native VAO 0, as RestoreAllAttributes can't fully restore
4250 // other VAOs.
4251 if (feature_info_->feature_flags().native_vertex_array_object)
4252 glBindVertexArrayOES(0);
4253
[email protected]cd2ef752014-02-12 23:16:034254 for (uint32 i = 0; i < group_->max_vertex_attribs(); ++i) {
4255 if (i != 0) // Never disable attribute 0
4256 glDisableVertexAttribArray(i);
4257 if(features().angle_instanced_arrays)
4258 glVertexAttribDivisorANGLE(i, 0);
4259 }
4260}
4261
4262void GLES2DecoderImpl::RestoreAllAttributes() const {
[email protected]81f20a622014-04-18 01:54:524263 state_.RestoreVertexAttribs();
[email protected]cd2ef752014-02-12 23:16:034264}
4265
[email protected]454157e2014-05-03 02:49:454266void GLES2DecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
4267 state_.SetIgnoreCachedStateForTest(ignore);
4268}
4269
[email protected]70d34263c2013-01-09 00:27:454270void GLES2DecoderImpl::OnFboChanged() const {
4271 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:514272 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
ccameron4ff12a732014-12-12 21:38:194273
4274 if (workarounds().gl_begin_gl_end_on_fbo_change_to_backbuffer) {
4275 GLint bound_fbo_unsigned = -1;
4276 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &bound_fbo_unsigned);
4277 GLuint bound_fbo = static_cast<GLuint>(bound_fbo_unsigned);
4278 if (surface_ && surface_->GetBackingFrameBufferObject() == bound_fbo)
4279 surface_->NotifyWasBound();
4280 }
[email protected]28718a92013-04-04 12:12:514281}
4282
4283// Called after the FBO is checked for completeness.
4284void GLES2DecoderImpl::OnUseFramebuffer() const {
4285 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
4286 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:324287 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:514288 glScissor(state_.scissor_x,
4289 state_.scissor_y,
4290 state_.scissor_width,
4291 state_.scissor_height);
4292
4293 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
4294 // it's unclear how this bug works.
4295 glFlush();
4296 }
[email protected]b177ae22011-11-01 03:29:114297}
4298
[email protected]051b1372010-04-12 02:42:084299void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:064300 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:084301 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034302 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:064303 framebuffer = GetFramebuffer(client_id);
4304 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:354305 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224306 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4307 "glBindFramebuffer",
4308 "id not generated by glGenFramebuffers");
4309 return;
[email protected]bf5a8d132011-08-16 08:39:354310 }
4311
[email protected]4d8f0dd2013-03-09 14:37:064312 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:034313 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354314 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:064315 framebuffer = GetFramebuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034316 } else {
[email protected]4d8f0dd2013-03-09 14:37:064317 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:084318 }
[email protected]4d8f0dd2013-03-09 14:37:064319 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084320 }
[email protected]4d8f0dd2013-03-09 14:37:064321 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:304322
4323 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344324 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304325 }
[email protected]cac16542014-01-15 17:53:514326
4327 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:304328 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:344329 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:304330 }
[email protected]6217d392010-03-25 22:08:354331
[email protected]c986af502013-08-14 01:04:444332 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464333
[email protected]b177ae22011-11-01 03:29:114334 // If we are rendering to the backbuffer get the FBO id for any simulated
4335 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:064336 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:114337 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:464338 }
[email protected]6217d392010-03-25 22:08:354339
[email protected]051b1372010-04-12 02:42:084340 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:454341 OnFboChanged();
[email protected]86093972010-03-11 00:13:564342}
4343
[email protected]051b1372010-04-12 02:42:084344void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:274345 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:084346 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034347 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:274348 renderbuffer = GetRenderbuffer(client_id);
4349 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:354350 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224351 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4352 "glBindRenderbuffer",
4353 "id not generated by glGenRenderbuffers");
[email protected]bf5a8d132011-08-16 08:39:354354 return;
4355 }
4356
[email protected]8875a5f2014-06-27 08:33:474357 // It's a new id so make a renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:034358 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:354359 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:274360 renderbuffer = GetRenderbuffer(client_id);
[email protected]ae51d192010-04-27 00:48:034361 } else {
[email protected]ee2a79c32013-03-10 03:50:274362 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:084363 }
[email protected]ee2a79c32013-03-10 03:50:274364 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:084365 }
[email protected]caa13ed2014-02-17 11:29:204366 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenderbuffer");
[email protected]ee2a79c32013-03-10 03:50:274367 state_.bound_renderbuffer = renderbuffer;
[email protected]8875a5f2014-06-27 08:33:474368 state_.bound_renderbuffer_valid = true;
4369 glBindRenderbufferEXT(GL_RENDERBUFFER, service_id);
[email protected]86093972010-03-11 00:13:564370}
4371
[email protected]051b1372010-04-12 02:42:084372void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:494373 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:084374 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:034375 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:494376 texture_ref = GetTexture(client_id);
4377 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:354378 if (!group_->bind_generates_resource()) {
[email protected]7ed37cc2014-02-12 11:15:224379 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4380 "glBindTexture",
4381 "id not generated by glGenTextures");
4382 return;
[email protected]bf5a8d132011-08-16 08:39:354383 }
4384
[email protected]02965c22013-03-09 02:40:074385 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:034386 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:414387 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:354388 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:494389 texture_ref = GetTexture(client_id);
[email protected]ae51d192010-04-27 00:48:034390 }
4391 } else {
[email protected]370eaf12013-05-18 09:19:494392 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:084393 }
[email protected]ae51d192010-04-27 00:48:034394
[email protected]1958e0e2010-04-22 05:17:154395 // Check the texture exists
[email protected]5ebf59f2014-04-08 03:51:574396 if (texture_ref) {
4397 Texture* texture = texture_ref->texture();
4398 // Check that we are not trying to bind it to a different target.
4399 if (texture->target() != 0 && texture->target() != target) {
4400 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4401 "glBindTexture",
4402 "texture bound to more than 1 target.");
4403 return;
4404 }
4405 LogClientServiceForInfo(texture, client_id, "glBindTexture");
4406 if (texture->target() == 0) {
4407 texture_manager()->SetTarget(texture_ref, target);
4408 }
4409 glBindTexture(target, texture->service_id());
4410 } else {
4411 glBindTexture(target, 0);
[email protected]1958e0e2010-04-22 05:17:154412 }
[email protected]32145a92012-12-17 09:01:594413
[email protected]e259eb412012-10-13 05:47:244414 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:504415 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:474416 switch (target) {
4417 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:494418 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:474419 break;
4420 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:494421 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:474422 break;
[email protected]61eeb33f2011-07-26 15:30:314423 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:494424 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:314425 break;
[email protected]e51bdf32011-11-23 22:21:464426 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:494427 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:464428 break;
[email protected]a93bb842010-02-16 23:03:474429 default:
4430 NOTREACHED(); // Validation should prevent us getting here.
4431 break;
4432 }
4433}
4434
[email protected]07f54fcc2009-12-22 02:46:304435void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244436 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:124437 if (index != 0 ||
4438 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:244439 glDisableVertexAttribArray(index);
4440 }
[email protected]07f54fcc2009-12-22 02:46:304441 } else {
[email protected]ab09b612013-03-11 22:11:514442 LOCAL_SET_GL_ERROR(
4443 GL_INVALID_VALUE,
4444 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304445 }
4446}
4447
[email protected]60f22d32012-12-12 00:31:584448void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4449 GLsizei numAttachments,
4450 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:354451 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:584452 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4453
4454 // Validates the attachments. If one of them fails
4455 // the whole command fails.
4456 for (GLsizei i = 0; i < numAttachments; ++i) {
4457 if ((framebuffer &&
4458 !validators_->attachment.IsValid(attachments[i])) ||
4459 (!framebuffer &&
4460 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514461 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4462 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584463 return;
4464 }
4465 }
4466
4467 // Marks each one of them as not cleared
4468 for (GLsizei i = 0; i < numAttachments; ++i) {
4469 if (framebuffer) {
4470 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4471 texture_manager(),
4472 attachments[i],
4473 false);
4474 } else {
4475 switch (attachments[i]) {
4476 case GL_COLOR_EXT:
4477 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4478 break;
4479 case GL_DEPTH_EXT:
4480 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4481 case GL_STENCIL_EXT:
4482 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4483 break;
4484 default:
4485 NOTREACHED();
4486 break;
4487 }
4488 }
4489 }
4490
[email protected]d49c5402013-09-11 15:39:024491 // If the default framebuffer is bound but we are still rendering to an
4492 // FBO, translate attachment names that refer to default framebuffer
4493 // channels to corresponding framebuffer attachments.
4494 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4495 for (GLsizei i = 0; i < numAttachments; ++i) {
4496 GLenum attachment = attachments[i];
4497 if (!framebuffer && GetBackbufferServiceId()) {
4498 switch (attachment) {
4499 case GL_COLOR_EXT:
4500 attachment = GL_COLOR_ATTACHMENT0;
4501 break;
4502 case GL_DEPTH_EXT:
4503 attachment = GL_DEPTH_ATTACHMENT;
4504 break;
4505 case GL_STENCIL_EXT:
4506 attachment = GL_STENCIL_ATTACHMENT;
4507 break;
4508 default:
4509 NOTREACHED();
4510 return;
4511 }
4512 }
4513 translated_attachments[i] = attachment;
4514 }
4515
boliu2e7d8a7a2014-10-16 20:35:204516 ScopedRenderTo do_render(framebuffer);
zmo68fcdc62014-12-05 21:51:494517 if (feature_info_->gl_version_info().is_es3) {
4518 glInvalidateFramebuffer(
4519 target, numAttachments, translated_attachments.get());
4520 } else {
4521 glDiscardFramebufferEXT(
4522 target, numAttachments, translated_attachments.get());
4523 }
[email protected]60f22d32012-12-12 00:31:584524}
4525
[email protected]07f54fcc2009-12-22 02:46:304526void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244527 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304528 glEnableVertexAttribArray(index);
4529 } else {
[email protected]ab09b612013-03-11 22:11:514530 LOCAL_SET_GL_ERROR(
4531 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304532 }
4533}
4534
[email protected]a93bb842010-02-16 23:03:474535void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444536 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4537 &state_, target);
[email protected]370eaf12013-05-18 09:19:494538 if (!texture_ref ||
4539 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514540 LOCAL_SET_GL_ERROR(
4541 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474542 return;
4543 }
[email protected]38c0a972012-05-12 00:48:024544
[email protected]12d95352012-12-14 07:23:544545 if (target == GL_TEXTURE_CUBE_MAP) {
4546 for (int i = 0; i < 6; ++i) {
4547 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494548 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514549 LOCAL_SET_GL_ERROR(
4550 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544551 return;
4552 }
4553 }
4554 } else {
[email protected]370eaf12013-05-18 09:19:494555 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514556 LOCAL_SET_GL_ERROR(
4557 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544558 return;
4559 }
[email protected]7687479c2012-05-14 23:54:044560 }
4561
[email protected]ab09b612013-03-11 22:11:514562 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194563 // Workaround for Mac driver bug. In the large scheme of things setting
4564 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564565 // hit so there's probably no need to make this conditional. The bug appears
4566 // to be that if the filtering mode is set to something that doesn't require
4567 // mipmaps for rendering, or is never set to something other than the default,
4568 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154569 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194570 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4571 }
[email protected]a93bb842010-02-16 23:03:474572 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154573 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494574 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4575 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194576 }
[email protected]ab09b612013-03-11 22:11:514577 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024578 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494579 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024580 }
[email protected]a93bb842010-02-16 23:03:474581}
4582
[email protected]b273e432010-04-12 17:23:584583bool GLES2DecoderImpl::GetHelper(
4584 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584585 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154586 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4587 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434588 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4589 *num_written = 1;
[email protected]c959a09a2014-03-27 11:44:214590 // Return the GL implementation's preferred format and (see below type)
4591 // if we have the GL extension that exposes this. This allows the GPU
4592 // client to use the implementation's preferred format for glReadPixels
4593 // for optimisation.
4594 //
4595 // A conflicting extension (GL_ARB_ES2_compatibility) specifies an error
4596 // case when requested on integer/floating point buffers but which is
4597 // acceptable on GLES2 and with the GL_OES_read_format extension.
4598 //
4599 // Therefore if an error occurs we swallow the error and use the
4600 // internal implementation.
[email protected]ad84a3a2012-06-08 21:42:434601 if (params) {
[email protected]c959a09a2014-03-27 11:44:214602 if (context_->HasExtension("GL_OES_read_format")) {
4603 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4604 GetErrorState());
4605 glGetIntegerv(pname, params);
4606 if (glGetError() == GL_NO_ERROR)
4607 return true;
4608 }
[email protected]68586372013-12-11 01:27:594609 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4610 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434611 }
4612 return true;
4613 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4614 *num_written = 1;
4615 if (params) {
[email protected]c959a09a2014-03-27 11:44:214616 if (context_->HasExtension("GL_OES_read_format")) {
4617 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::GetHelper",
4618 GetErrorState());
4619 glGetIntegerv(pname, params);
4620 if (glGetError() == GL_NO_ERROR)
4621 return true;
4622 }
[email protected]68586372013-12-11 01:27:594623 *params = GLES2Util::GetPreferredGLReadPixelsType(
4624 GetBoundReadFrameBufferInternalFormat(),
4625 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434626 }
4627 return true;
4628 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4629 *num_written = 1;
4630 if (params) {
4631 *params = group_->max_fragment_uniform_vectors();
4632 }
4633 return true;
4634 case GL_MAX_VARYING_VECTORS:
4635 *num_written = 1;
4636 if (params) {
4637 *params = group_->max_varying_vectors();
4638 }
4639 return true;
4640 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4641 *num_written = 1;
4642 if (params) {
4643 *params = group_->max_vertex_uniform_vectors();
4644 }
4645 return true;
[email protected]4e8a5b122010-05-08 22:00:104646 }
[email protected]5cb735d2011-10-13 01:37:234647 }
4648 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244649 case GL_MAX_VIEWPORT_DIMS:
4650 if (offscreen_target_frame_buffer_.get()) {
4651 *num_written = 2;
4652 if (params) {
4653 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4654 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4655 }
4656 return true;
4657 }
[email protected]5cb735d2011-10-13 01:37:234658 return false;
[email protected]84afefa2011-10-19 21:45:534659 case GL_MAX_SAMPLES:
4660 *num_written = 1;
4661 if (params) {
4662 params[0] = renderbuffer_manager()->max_samples();
4663 }
4664 return true;
4665 case GL_MAX_RENDERBUFFER_SIZE:
4666 *num_written = 1;
4667 if (params) {
4668 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4669 }
4670 return true;
[email protected]5cb735d2011-10-13 01:37:234671 case GL_MAX_TEXTURE_SIZE:
4672 *num_written = 1;
4673 if (params) {
4674 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4675 }
4676 return true;
4677 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4678 *num_written = 1;
4679 if (params) {
4680 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4681 }
4682 return true;
[email protected]2f143d482013-03-14 18:04:494683 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4684 *num_written = 1;
4685 if (params) {
4686 params[0] = group_->max_color_attachments();
4687 }
4688 return true;
4689 case GL_MAX_DRAW_BUFFERS_ARB:
4690 *num_written = 1;
4691 if (params) {
4692 params[0] = group_->max_draw_buffers();
4693 }
4694 return true;
[email protected]297ca1c2011-06-20 23:08:464695 case GL_ALPHA_BITS:
4696 *num_written = 1;
4697 if (params) {
4698 GLint v = 0;
4699 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544700 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464701 }
4702 return true;
4703 case GL_DEPTH_BITS:
4704 *num_written = 1;
4705 if (params) {
4706 GLint v = 0;
4707 glGetIntegerv(GL_DEPTH_BITS, &v);
4708 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4709 }
4710 return true;
4711 case GL_STENCIL_BITS:
4712 *num_written = 1;
4713 if (params) {
4714 GLint v = 0;
4715 glGetIntegerv(GL_STENCIL_BITS, &v);
4716 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4717 }
4718 return true;
[email protected]656dcaad2010-05-07 17:18:374719 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114720 *num_written = validators_->compressed_texture_format.GetValues().size();
4721 if (params) {
4722 for (GLint ii = 0; ii < *num_written; ++ii) {
4723 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4724 }
4725 }
[email protected]656dcaad2010-05-07 17:18:374726 return true;
[email protected]b273e432010-04-12 17:23:584727 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4728 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104729 if (params) {
[email protected]302ce6d2011-07-07 23:28:114730 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104731 }
[email protected]b273e432010-04-12 17:23:584732 return true;
4733 case GL_NUM_SHADER_BINARY_FORMATS:
4734 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104735 if (params) {
[email protected]302ce6d2011-07-07 23:28:114736 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104737 }
[email protected]b273e432010-04-12 17:23:584738 return true;
4739 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114740 *num_written = validators_->shader_binary_format.GetValues().size();
4741 if (params) {
4742 for (GLint ii = 0; ii < *num_written; ++ii) {
4743 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4744 }
4745 }
4746 return true;
[email protected]b273e432010-04-12 17:23:584747 case GL_SHADER_COMPILER:
4748 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104749 if (params) {
4750 *params = GL_TRUE;
4751 }
[email protected]b273e432010-04-12 17:23:584752 return true;
[email protected]6b8cf1a2010-05-06 16:13:584753 case GL_ARRAY_BUFFER_BINDING:
4754 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104755 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114756 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104757 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244758 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104759 &client_id);
4760 *params = client_id;
4761 } else {
4762 *params = 0;
4763 }
[email protected]6b8cf1a2010-05-06 16:13:584764 }
4765 return true;
4766 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4767 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104768 if (params) {
[email protected]e259eb412012-10-13 05:47:244769 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104770 GLuint client_id = 0;
4771 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254772 state_.vertex_attrib_manager->element_array_buffer()->
4773 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104774 *params = client_id;
4775 } else {
4776 *params = 0;
4777 }
[email protected]6b8cf1a2010-05-06 16:13:584778 }
4779 return true;
4780 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304781 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584782 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104783 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354784 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454785 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204786 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104787 GLuint client_id = 0;
4788 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204789 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304790 *params = client_id;
4791 } else {
4792 *params = 0;
4793 }
4794 }
4795 return true;
[email protected]ebfb73c2012-08-15 02:37:454796 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304797 *num_written = 1;
4798 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354799 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454800 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204801 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304802 GLuint client_id = 0;
4803 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204804 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104805 *params = client_id;
4806 } else {
4807 *params = 0;
4808 }
[email protected]6b8cf1a2010-05-06 16:13:584809 }
4810 return true;
4811 case GL_RENDERBUFFER_BINDING:
4812 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104813 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354814 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204815 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4816 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104817 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104818 } else {
4819 *params = 0;
4820 }
[email protected]6b8cf1a2010-05-06 16:13:584821 }
4822 return true;
4823 case GL_CURRENT_PROGRAM:
4824 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104825 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114826 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104827 GLuint client_id = 0;
4828 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244829 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104830 *params = client_id;
4831 } else {
4832 *params = 0;
4833 }
[email protected]6b8cf1a2010-05-06 16:13:584834 }
4835 return true;
[email protected]bf835842012-11-19 15:21:514836 case GL_VERTEX_ARRAY_BINDING_OES:
4837 *num_written = 1;
4838 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114839 if (state_.vertex_attrib_manager.get() !=
[email protected]81f20a622014-04-18 01:54:524840 state_.default_vertex_attrib_manager.get()) {
[email protected]bf835842012-11-19 15:21:514841 GLuint client_id = 0;
4842 vertex_array_manager_->GetClientId(
4843 state_.vertex_attrib_manager->service_id(), &client_id);
4844 *params = client_id;
4845 } else {
4846 *params = 0;
4847 }
4848 }
4849 return true;
[email protected]4e8a5b122010-05-08 22:00:104850 case GL_TEXTURE_BINDING_2D:
4851 *num_written = 1;
4852 if (params) {
[email protected]e259eb412012-10-13 05:47:244853 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114854 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104855 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584856 } else {
4857 *params = 0;
4858 }
[email protected]6b8cf1a2010-05-06 16:13:584859 }
[email protected]4e8a5b122010-05-08 22:00:104860 return true;
4861 case GL_TEXTURE_BINDING_CUBE_MAP:
4862 *num_written = 1;
4863 if (params) {
[email protected]e259eb412012-10-13 05:47:244864 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114865 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104866 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584867 } else {
4868 *params = 0;
4869 }
[email protected]6b8cf1a2010-05-06 16:13:584870 }
[email protected]4e8a5b122010-05-08 22:00:104871 return true;
[email protected]61eeb33f2011-07-26 15:30:314872 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4873 *num_written = 1;
4874 if (params) {
[email protected]e259eb412012-10-13 05:47:244875 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114876 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104877 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314878 } else {
4879 *params = 0;
4880 }
4881 }
4882 return true;
[email protected]e51bdf32011-11-23 22:21:464883 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4884 *num_written = 1;
4885 if (params) {
[email protected]e259eb412012-10-13 05:47:244886 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114887 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104888 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464889 } else {
4890 *params = 0;
4891 }
4892 }
4893 return true;
[email protected]6c75c712012-06-19 15:43:174894 case GL_UNPACK_FLIP_Y_CHROMIUM:
4895 *num_written = 1;
4896 if (params) {
4897 params[0] = unpack_flip_y_;
4898 }
4899 return true;
4900 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4901 *num_written = 1;
4902 if (params) {
4903 params[0] = unpack_premultiply_alpha_;
4904 }
4905 return true;
4906 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4907 *num_written = 1;
4908 if (params) {
4909 params[0] = unpack_unpremultiply_alpha_;
4910 }
4911 return true;
[email protected]6eda6822014-04-03 23:00:504912 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
4913 *num_written = 1;
4914 if (params) {
4915 params[0] = group_->bind_generates_resource() ? 1 : 0;
4916 }
4917 return true;
[email protected]b273e432010-04-12 17:23:584918 default:
[email protected]2f143d482013-03-14 18:04:494919 if (pname >= GL_DRAW_BUFFER0_ARB &&
4920 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4921 *num_written = 1;
4922 if (params) {
4923 Framebuffer* framebuffer =
4924 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4925 if (framebuffer) {
4926 params[0] = framebuffer->GetDrawBuffer(pname);
4927 } else { // backbuffer
4928 if (pname == GL_DRAW_BUFFER0_ARB)
4929 params[0] = group_->draw_buffer();
4930 else
4931 params[0] = GL_NONE;
4932 }
4933 }
4934 return true;
4935 }
[email protected]4e8a5b122010-05-08 22:00:104936 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534937 return false;
[email protected]b273e432010-04-12 17:23:584938 }
4939}
4940
[email protected]4e8a5b122010-05-08 22:00:104941bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4942 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264943 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534944 return true;
4945 }
[email protected]4e8a5b122010-05-08 22:00:104946 return GetHelper(pname, NULL, num_values);
4947}
4948
[email protected]7d3c36e2013-07-12 14:13:164949GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4950 if (GL_MAX_SAMPLES == pname &&
4951 features().use_img_for_multisampled_render_to_texture) {
4952 return GL_MAX_SAMPLES_IMG;
4953 }
4954 return pname;
4955}
4956
[email protected]b273e432010-04-12 17:23:584957void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4958 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104959 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534960 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554961 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264962 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534963 GetHelper(pname, values.get(), &num_written);
4964 }
[email protected]b273e432010-04-12 17:23:584965 for (GLsizei ii = 0; ii < num_written; ++ii) {
4966 params[ii] = static_cast<GLboolean>(values[ii]);
4967 }
4968 } else {
[email protected]7d3c36e2013-07-12 14:13:164969 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584970 glGetBooleanv(pname, params);
4971 }
4972}
4973
4974void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4975 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104976 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264977 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534978 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554979 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534980 GetHelper(pname, values.get(), &num_written);
4981 for (GLsizei ii = 0; ii < num_written; ++ii) {
4982 params[ii] = static_cast<GLfloat>(values[ii]);
4983 }
4984 } else {
[email protected]7d3c36e2013-07-12 14:13:164985 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534986 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584987 }
[email protected]b273e432010-04-12 17:23:584988 }
4989}
4990
4991void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4992 DCHECK(params);
4993 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264994 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534995 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:164996 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584997 glGetIntegerv(pname, params);
4998 }
4999}
5000
[email protected]a0c3e972010-04-21 00:49:135001void GLES2DecoderImpl::DoGetProgramiv(
5002 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:425003 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
5004 if (!program) {
[email protected]a0c3e972010-04-21 00:49:135005 return;
5006 }
[email protected]df37b9932013-03-08 05:21:425007 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:135008}
5009
[email protected]17cfbe0e2013-03-07 01:26:085010void GLES2DecoderImpl::DoGetBufferParameteriv(
5011 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:135012 // Just delegate it. Some validation is actually done before this.
5013 buffer_manager()->ValidateAndDoGetBufferParameteriv(
5014 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:085015}
5016
[email protected]258a3313f2011-10-18 20:13:575017void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:425018 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:575019 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:515020 LOCAL_SET_GL_ERROR(
5021 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:575022 return;
5023 }
[email protected]68dcb1f2012-04-07 00:14:565024 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:515025 LOCAL_SET_GL_ERROR(
5026 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:565027 return;
5028 }
5029 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:515030 LOCAL_SET_GL_ERROR(
5031 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:565032 return;
5033 }
[email protected]df37b9932013-03-08 05:21:425034 Program* program = GetProgramInfoNotShader(
5035 program_id, "glBindAttribLocation");
5036 if (!program) {
[email protected]258a3313f2011-10-18 20:13:575037 return;
[email protected]558847a2010-03-24 07:02:545038 }
zmo460b593e2014-10-13 23:07:455039 // At this point, the program's shaders may not be translated yet,
5040 // therefore, we may not find the hashed attribute name.
5041 // glBindAttribLocation call with original name is useless.
5042 // So instead, we should simply cache the binding, and then call
5043 // Program::ExecuteBindAttribLocationCalls() right before link.
[email protected]df37b9932013-03-08 05:21:425044 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
zmo460b593e2014-10-13 23:07:455045 // TODO(zmo): Get rid of the following glBindAttribLocation call.
[email protected]df37b9932013-03-08 05:21:425046 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:575047}
5048
[email protected]558847a2010-03-24 07:02:545049error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
vmiuracd108592014-09-08 14:36:345050 uint32 immediate_data_size,
5051 const void* cmd_data) {
5052 const gles2::cmds::BindAttribLocationBucket& c =
5053 *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data);
[email protected]6b8cf1a2010-05-06 16:13:585054 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:545055 GLuint index = static_cast<GLuint>(c.index);
5056 Bucket* bucket = GetBucket(c.name_bucket_id);
5057 if (!bucket || bucket->size() == 0) {
5058 return error::kInvalidArguments;
5059 }
5060 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:185061 if (!bucket->GetAsString(&name_str)) {
5062 return error::kInvalidArguments;
5063 }
[email protected]258a3313f2011-10-18 20:13:575064 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:545065 return error::kNoError;
5066}
5067
[email protected]2be6abf32012-06-26 00:28:335068void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:425069 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:335070 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:515071 LOCAL_SET_GL_ERROR(
5072 GL_INVALID_VALUE,
5073 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:335074 return;
5075 }
5076 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:515077 LOCAL_SET_GL_ERROR(
5078 GL_INVALID_OPERATION,
5079 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:335080 return;
5081 }
5082 if (location < 0 || static_cast<uint32>(location) >=
5083 (group_->max_fragment_uniform_vectors() +
5084 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:515085 LOCAL_SET_GL_ERROR(
5086 GL_INVALID_VALUE,
5087 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335088 return;
5089 }
[email protected]df37b9932013-03-08 05:21:425090 Program* program = GetProgramInfoNotShader(
5091 program_id, "glBindUniformLocationCHROMIUM");
5092 if (!program) {
[email protected]2be6abf32012-06-26 00:28:335093 return;
5094 }
[email protected]df37b9932013-03-08 05:21:425095 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:515096 LOCAL_SET_GL_ERROR(
5097 GL_INVALID_VALUE,
5098 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:335099 }
5100}
5101
[email protected]2be6abf32012-06-26 00:28:335102error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
5103 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:345104 const void* cmd_data) {
5105 const gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
5106 *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
5107 cmd_data);
[email protected]2be6abf32012-06-26 00:28:335108 GLuint program = static_cast<GLuint>(c.program);
5109 GLint location = static_cast<GLint>(c.location);
5110 Bucket* bucket = GetBucket(c.name_bucket_id);
5111 if (!bucket || bucket->size() == 0) {
5112 return error::kInvalidArguments;
5113 }
5114 std::string name_str;
5115 if (!bucket->GetAsString(&name_str)) {
5116 return error::kInvalidArguments;
5117 }
5118 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
5119 return error::kNoError;
5120}
5121
vmiuracd108592014-09-08 14:36:345122error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size,
5123 const void* cmd_data) {
5124 const gles2::cmds::DeleteShader& c =
5125 *static_cast<const gles2::cmds::DeleteShader*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035126 GLuint client_id = c.shader;
5127 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425128 Shader* shader = GetShader(client_id);
5129 if (shader) {
5130 if (!shader->IsDeleted()) {
5131 glDeleteShader(shader->service_id());
5132 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:145133 }
[email protected]ae51d192010-04-27 00:48:035134 } else {
[email protected]ab09b612013-03-11 22:11:515135 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:035136 }
[email protected]96449d2c2009-11-25 00:01:325137 }
[email protected]f7a64ee2010-02-01 22:24:145138 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325139}
5140
vmiuracd108592014-09-08 14:36:345141error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size,
5142 const void* cmd_data) {
5143 const gles2::cmds::DeleteProgram& c =
5144 *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data);
[email protected]ae51d192010-04-27 00:48:035145 GLuint client_id = c.program;
5146 if (client_id) {
[email protected]df37b9932013-03-08 05:21:425147 Program* program = GetProgram(client_id);
5148 if (program) {
5149 if (!program->IsDeleted()) {
5150 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:145151 }
[email protected]ae51d192010-04-27 00:48:035152 } else {
[email protected]ab09b612013-03-11 22:11:515153 LOCAL_SET_GL_ERROR(
5154 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:035155 }
[email protected]96449d2c2009-11-25 00:01:325156 }
[email protected]f7a64ee2010-02-01 22:24:145157 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:325158}
5159
[email protected]a7266a92012-06-28 02:11:085160error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:445161 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:205162 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:465163 ApplyDirtyState();
boliu2e7d8a7a2014-10-16 20:35:205164 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
sievers2384f2b2014-11-18 02:10:355165 if (workarounds().gl_clear_broken) {
5166 ScopedGLErrorSuppressor suppressor("GLES2DecoderImpl::ClearWorkaround",
5167 GetErrorState());
5168 if (!BoundFramebufferHasDepthAttachment())
5169 mask &= ~GL_DEPTH_BUFFER_BIT;
5170 if (!BoundFramebufferHasStencilAttachment())
5171 mask &= ~GL_STENCIL_BUFFER_BIT;
5172 clear_framebuffer_blit_->ClearFramebuffer(
5173 this, GetBoundReadFrameBufferSize(), mask, state_.color_clear_red,
5174 state_.color_clear_green, state_.color_clear_blue,
5175 state_.color_clear_alpha, state_.depth_clear, state_.stencil_clear);
5176 return error::kNoError;
5177 }
[email protected]3a03a8f2011-03-19 00:51:275178 glClear(mask);
5179 }
[email protected]a7266a92012-06-28 02:11:085180 return error::kNoError;
5181}
5182
[email protected]36cef8ce2010-03-16 07:34:455183void GLES2DecoderImpl::DoFramebufferRenderbuffer(
5184 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:035185 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:065186 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5187 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515188 LOCAL_SET_GL_ERROR(
5189 GL_INVALID_OPERATION,
5190 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455191 return;
5192 }
[email protected]ae51d192010-04-27 00:48:035193 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:275194 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:035195 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:275196 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
5197 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515198 LOCAL_SET_GL_ERROR(
5199 GL_INVALID_OPERATION,
5200 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:035201 return;
5202 }
[email protected]ee2a79c32013-03-10 03:50:275203 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:035204 }
[email protected]ab09b612013-03-11 22:11:515205 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:035206 glFramebufferRenderbufferEXT(
5207 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:515208 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:265209 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:275210 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:285211 }
[email protected]9d3b2e12013-10-02 01:04:345212 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445213 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465214 }
[email protected]81fc9d02013-03-14 23:53:325215 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:285216}
5217
[email protected]3a2e7c7b2010-08-06 01:12:285218void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465219 if (SetCapabilityState(cap, false)) {
5220 glDisable(cap);
5221 }
[email protected]3a2e7c7b2010-08-06 01:12:285222}
5223
5224void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:465225 if (SetCapabilityState(cap, true)) {
5226 glEnable(cap);
5227 }
[email protected]3a2e7c7b2010-08-06 01:12:285228}
5229
[email protected]88a61bf2012-10-27 13:00:425230void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
5231 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
5232 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
5233 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:285234}
5235
[email protected]b04e24c2013-01-08 18:35:255236void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:425237 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
5238 state_.sample_coverage_invert = (invert != 0);
5239 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:285240}
5241
[email protected]0d6bfdc2011-11-02 01:32:205242// Assumes framebuffer is complete.
5243void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:065244 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:305245 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:205246 // bind this to the DRAW point, clear then bind back to READ
5247 // TODO(gman): I don't think there is any guarantee that an FBO that
5248 // is complete on the READ attachment will be complete as a DRAW
5249 // attachment.
5250 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:065251 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:305252 }
[email protected]3a2e7c7b2010-08-06 01:12:285253 GLbitfield clear_bits = 0;
[email protected]ee757922014-06-06 05:21:425254 if (framebuffer->HasUnclearedColorAttachments()) {
[email protected]297ca1c2011-06-20 23:08:465255 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:205256 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:465257 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:065258 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
5259 1.0f);
[email protected]454157e2014-05-03 02:49:455260 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285261 clear_bits |= GL_COLOR_BUFFER_BIT;
[email protected]0e58af82014-08-08 14:02:535262 if (feature_info_->feature_flags().ext_draw_buffers)
5263 framebuffer->PrepareDrawBuffersForClear();
[email protected]3a2e7c7b2010-08-06 01:12:285264 }
5265
[email protected]4d8f0dd2013-03-09 14:37:065266 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
5267 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285268 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:475269 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
5270 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]3a2e7c7b2010-08-06 01:12:285271 clear_bits |= GL_STENCIL_BUFFER_BIT;
5272 }
5273
[email protected]4d8f0dd2013-03-09 14:37:065274 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
5275 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:285276 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:455277 state_.SetDeviceDepthMask(GL_TRUE);
[email protected]3a2e7c7b2010-08-06 01:12:285278 clear_bits |= GL_DEPTH_BUFFER_BIT;
5279 }
5280
[email protected]454157e2014-05-03 02:49:455281 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]3a2e7c7b2010-08-06 01:12:285282 glClear(clear_bits);
5283
brucedawson18249152014-10-31 23:02:325284 if ((clear_bits & GL_COLOR_BUFFER_BIT) != 0 &&
[email protected]0e58af82014-08-08 14:02:535285 feature_info_->feature_flags().ext_draw_buffers)
[email protected]ee757922014-06-06 05:21:425286 framebuffer->RestoreDrawBuffersAfterClear();
5287
[email protected]968351b2011-12-20 08:26:515288 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:065289 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:285290
[email protected]c007aa02010-09-02 22:22:405291 RestoreClearState();
5292
5293 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:065294 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
5295 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:485296 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:065297 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
5298 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:485299 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:405300 }
5301}
5302
5303void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:445304 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:245305 glClearColor(
5306 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
5307 state_.color_clear_alpha);
5308 glClearStencil(state_.stencil_clear);
5309 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:225310 if (state_.enable_flags.scissor_test) {
[email protected]454157e2014-05-03 02:49:455311 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]3a2e7c7b2010-08-06 01:12:285312 }
[email protected]36cef8ce2010-03-16 07:34:455313}
5314
5315GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:355316 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:305317 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:205318 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:455319 return GL_FRAMEBUFFER_COMPLETE;
5320 }
[email protected]0d6bfdc2011-11-02 01:32:205321 GLenum completeness = framebuffer->IsPossiblyComplete();
5322 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
5323 return completeness;
5324 }
[email protected]73276522012-11-09 05:50:205325 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:455326}
5327
5328void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:035329 GLenum target, GLenum attachment, GLenum textarget,
5330 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:165331 DoFramebufferTexture2DCommon(
5332 "glFramebufferTexture2D", target, attachment,
5333 textarget, client_texture_id, level, 0);
5334}
5335
5336void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
5337 GLenum target, GLenum attachment, GLenum textarget,
5338 GLuint client_texture_id, GLint level, GLsizei samples) {
[email protected]7d3c36e2013-07-12 14:13:165339 DoFramebufferTexture2DCommon(
5340 "glFramebufferTexture2DMultisample", target, attachment,
5341 textarget, client_texture_id, level, samples);
5342}
5343
5344void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
5345 const char* name, GLenum target, GLenum attachment, GLenum textarget,
5346 GLuint client_texture_id, GLint level, GLsizei samples) {
5347 if (samples > renderbuffer_manager()->max_samples()) {
5348 LOCAL_SET_GL_ERROR(
5349 GL_INVALID_VALUE,
5350 "glFramebufferTexture2DMultisample", "samples too large");
5351 return;
5352 }
[email protected]4d8f0dd2013-03-09 14:37:065353 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5354 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515355 LOCAL_SET_GL_ERROR(
5356 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165357 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:455358 return;
5359 }
[email protected]ae51d192010-04-27 00:48:035360 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:495361 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:035362 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:495363 texture_ref = GetTexture(client_texture_id);
5364 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:515365 LOCAL_SET_GL_ERROR(
5366 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165367 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:035368 return;
5369 }
[email protected]370eaf12013-05-18 09:19:495370 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:035371 }
[email protected]0d6bfdc2011-11-02 01:32:205372
[email protected]80eb6b52012-01-19 00:14:415373 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:515374 LOCAL_SET_GL_ERROR(
5375 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:165376 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:205377 return;
5378 }
5379
[email protected]91c94eb2013-10-22 10:32:545380 if (texture_ref)
5381 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5382
[email protected]7d3c36e2013-07-12 14:13:165383 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5384 if (0 == samples) {
5385 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5386 } else {
5387 if (features().use_img_for_multisampled_render_to_texture) {
5388 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5389 service_id, level, samples);
5390 } else {
5391 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5392 service_id, level, samples);
5393 }
5394 }
5395 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265396 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165397 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5398 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285399 }
[email protected]9d3b2e12013-10-02 01:04:345400 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445401 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465402 }
[email protected]91c94eb2013-10-22 10:32:545403
5404 if (texture_ref)
5405 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5406
[email protected]81fc9d02013-03-14 23:53:325407 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455408}
5409
zmo84c08202014-11-23 15:28:405410void GLES2DecoderImpl::DoFramebufferTextureLayer(
5411 GLenum target, GLenum attachment, GLuint client_texture_id,
5412 GLint level, GLint layer) {
5413 // TODO(zmo): Unsafe ES3 API, missing states update.
5414 GLuint service_id = 0;
5415 TextureRef* texture_ref = NULL;
5416 if (client_texture_id) {
5417 texture_ref = GetTexture(client_texture_id);
5418 if (!texture_ref) {
5419 LOCAL_SET_GL_ERROR(
5420 GL_INVALID_OPERATION,
5421 "glFramebufferTextureLayer", "unknown texture_ref");
5422 return;
5423 }
5424 service_id = texture_ref->service_id();
5425 }
5426 glFramebufferTextureLayer(target, attachment, service_id, level, layer);
5427}
5428
[email protected]36cef8ce2010-03-16 07:34:455429void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5430 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065431 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5432 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515433 LOCAL_SET_GL_ERROR(
5434 GL_INVALID_OPERATION,
[email protected]caa13ed2014-02-17 11:29:205435 "glGetFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455436 return;
5437 }
[email protected]74c1ec42010-08-12 01:55:575438 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105439 const Framebuffer::Attachment* attachment_object =
5440 framebuffer->GetAttachment(attachment);
5441 *params = attachment_object ? attachment_object->object_name() : 0;
5442 } else {
[email protected]7d3c36e2013-07-12 14:13:165443 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5444 features().use_img_for_multisampled_render_to_texture) {
5445 pname = GL_TEXTURE_SAMPLES_IMG;
5446 }
[email protected]62e65f02013-05-29 22:28:105447 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575448 }
[email protected]36cef8ce2010-03-16 07:34:455449}
5450
5451void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5452 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355453 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205454 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5455 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515456 LOCAL_SET_GL_ERROR(
5457 GL_INVALID_OPERATION,
5458 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455459 return;
5460 }
[email protected]8875a5f2014-06-27 08:33:475461
5462 EnsureRenderbufferBound();
[email protected]3a03a8f2011-03-19 00:51:275463 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435464 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5465 *params = renderbuffer->internal_format();
5466 break;
5467 case GL_RENDERBUFFER_WIDTH:
5468 *params = renderbuffer->width();
5469 break;
5470 case GL_RENDERBUFFER_HEIGHT:
5471 *params = renderbuffer->height();
5472 break;
[email protected]7d3c36e2013-07-12 14:13:165473 case GL_RENDERBUFFER_SAMPLES_EXT:
5474 if (features().use_img_for_multisampled_render_to_texture) {
5475 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5476 params);
5477 } else {
5478 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5479 params);
5480 }
[email protected]ad84a3a2012-06-08 21:42:435481 default:
5482 glGetRenderbufferParameterivEXT(target, pname, params);
5483 break;
[email protected]b71f52c2010-06-18 22:20:205484 }
[email protected]36cef8ce2010-03-16 07:34:455485}
5486
[email protected]49cabed2013-11-13 18:15:185487void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305488 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5489 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5490 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445491 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]0c16343f2013-03-08 20:40:165492
[email protected]49cabed2013-11-13 18:15:185493 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165494 return;
5495 }
5496
[email protected]454157e2014-05-03 02:49:455497 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
boliu2e7d8a7a2014-10-16 20:35:205498 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]f42f05b2013-11-15 21:46:185499 BlitFramebufferHelper(
5500 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]454157e2014-05-03 02:49:455501 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST,
5502 state_.enable_flags.scissor_test);
[email protected]f42f05b2013-11-15 21:46:185503}
5504
[email protected]8875a5f2014-06-27 08:33:475505void GLES2DecoderImpl::EnsureRenderbufferBound() {
5506 if (!state_.bound_renderbuffer_valid) {
5507 state_.bound_renderbuffer_valid = true;
5508 glBindRenderbufferEXT(GL_RENDERBUFFER,
5509 state_.bound_renderbuffer.get()
5510 ? state_.bound_renderbuffer->service_id()
5511 : 0);
5512 }
5513}
5514
[email protected]f42f05b2013-11-15 21:46:185515void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5516 const FeatureInfo* feature_info,
5517 GLenum target,
5518 GLsizei samples,
5519 GLenum internal_format,
5520 GLsizei width,
5521 GLsizei height) {
5522 // TODO(sievers): This could be resolved at the GL binding level, but the
5523 // binding process is currently a bit too 'brute force'.
zmo68fcdc62014-12-05 21:51:495524 if (feature_info->gl_version_info().is_angle) {
[email protected]f42f05b2013-11-15 21:46:185525 glRenderbufferStorageMultisampleANGLE(
5526 target, samples, internal_format, width, height);
5527 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5528 glRenderbufferStorageMultisample(
5529 target, samples, internal_format, width, height);
5530 } else {
5531 glRenderbufferStorageMultisampleEXT(
5532 target, samples, internal_format, width, height);
5533 }
5534}
5535
5536void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5537 GLint srcY0,
5538 GLint srcX1,
5539 GLint srcY1,
5540 GLint dstX0,
5541 GLint dstY0,
5542 GLint dstX1,
5543 GLint dstY1,
5544 GLbitfield mask,
5545 GLenum filter) {
5546 // TODO(sievers): This could be resolved at the GL binding level, but the
5547 // binding process is currently a bit too 'brute force'.
zmo68fcdc62014-12-05 21:51:495548 if (feature_info_->gl_version_info().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245549 glBlitFramebufferANGLE(
5550 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185551 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5552 glBlitFramebuffer(
5553 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245554 } else {
5555 glBlitFramebufferEXT(
5556 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5557 }
[email protected]8e3e0662010-08-23 18:46:305558}
5559
[email protected]49cabed2013-11-13 18:15:185560bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5561 GLsizei samples,
5562 GLenum internalformat,
5563 GLsizei width,
5564 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535565 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515566 LOCAL_SET_GL_ERROR(
5567 GL_INVALID_VALUE,
5568 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185569 return false;
[email protected]84afefa2011-10-19 21:45:535570 }
5571
5572 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5573 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515574 LOCAL_SET_GL_ERROR(
5575 GL_INVALID_VALUE,
5576 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185577 return false;
[email protected]84afefa2011-10-19 21:45:535578 }
5579
[email protected]7989c9e2013-01-23 06:39:265580 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235581 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5582 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515583 LOCAL_SET_GL_ERROR(
5584 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205585 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185586 return false;
[email protected]8e3e0662010-08-23 18:46:305587 }
5588
[email protected]7989c9e2013-01-23 06:39:265589 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515590 LOCAL_SET_GL_ERROR(
5591 GL_OUT_OF_MEMORY,
[email protected]caa13ed2014-02-17 11:29:205592 "glRenderbufferStorageMultisample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185593 return false;
5594 }
5595
5596 return true;
5597}
5598
5599void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5600 GLenum target, GLsizei samples, GLenum internalformat,
5601 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185602 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5603 if (!renderbuffer) {
5604 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5605 "glRenderbufferStorageMultisampleCHROMIUM",
5606 "no renderbuffer bound");
5607 return;
5608 }
5609
5610 if (!ValidateRenderbufferStorageMultisample(
5611 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265612 return;
5613 }
5614
[email protected]8875a5f2014-06-27 08:33:475615 EnsureRenderbufferBound();
[email protected]8e102e102013-09-20 22:50:235616 GLenum impl_format =
5617 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5618 internalformat);
[email protected]49cabed2013-11-13 18:15:185619 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5620 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185621 RenderbufferStorageMultisampleHelper(
Daniel Cheng3d7ce9f2014-08-26 00:26:255622 feature_info_.get(), target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185623 GLenum error =
5624 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265625 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105626
5627 if (workarounds().validate_multisample_buffer_allocation) {
5628 if (!VerifyMultisampleRenderbufferIntegrity(
5629 renderbuffer->service_id(), impl_format)) {
5630 LOCAL_SET_GL_ERROR(
5631 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185632 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105633 return;
5634 }
5635 }
5636
[email protected]968351b2011-12-20 08:26:515637 // TODO(gman): If renderbuffers tracked which framebuffers they were
5638 // attached to we could just mark those framebuffers as not complete.
5639 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205640 renderbuffer_manager()->SetInfo(
5641 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265642 }
[email protected]8e3e0662010-08-23 18:46:305643}
5644
[email protected]49cabed2013-11-13 18:15:185645// This is the handler for multisampled_render_to_texture extensions.
5646void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5647 GLenum target, GLsizei samples, GLenum internalformat,
5648 GLsizei width, GLsizei height) {
[email protected]49cabed2013-11-13 18:15:185649 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5650 if (!renderbuffer) {
5651 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5652 "glRenderbufferStorageMultisampleEXT",
5653 "no renderbuffer bound");
5654 return;
5655 }
5656
5657 if (!ValidateRenderbufferStorageMultisample(
5658 samples, internalformat, width, height)) {
5659 return;
5660 }
5661
[email protected]8875a5f2014-06-27 08:33:475662 EnsureRenderbufferBound();
[email protected]49cabed2013-11-13 18:15:185663 GLenum impl_format =
5664 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5665 internalformat);
5666 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5667 if (features().use_img_for_multisampled_render_to_texture) {
5668 glRenderbufferStorageMultisampleIMG(
5669 target, samples, impl_format, width, height);
5670 } else {
5671 glRenderbufferStorageMultisampleEXT(
5672 target, samples, impl_format, width, height);
5673 }
5674 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5675 if (error == GL_NO_ERROR) {
5676 // TODO(gman): If renderbuffers tracked which framebuffers they were
5677 // attached to we could just mark those framebuffers as not complete.
5678 framebuffer_manager()->IncFramebufferStateChangeCount();
5679 renderbuffer_manager()->SetInfo(
5680 renderbuffer, samples, internalformat, width, height);
5681 }
5682}
5683
[email protected]4a4c18b2013-09-13 22:50:105684// This function validates the allocation of a multisampled renderbuffer
5685// by clearing it to a key color, blitting the contents to a texture, and
5686// reading back the color to ensure it matches the key.
5687bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5688 GLuint renderbuffer, GLenum format) {
5689
5690 // Only validate color buffers.
5691 // These formats have been selected because they are very common or are known
5692 // to be used by the WebGL backbuffer. If problems are observed with other
5693 // color formats they can be added here.
5694 switch(format) {
5695 case GL_RGB:
5696 case GL_RGB8:
5697 case GL_RGBA:
5698 case GL_RGBA8:
5699 break;
5700 default:
5701 return true;
5702 }
5703
5704 GLint draw_framebuffer, read_framebuffer;
5705
5706 // Cache framebuffer and texture bindings.
5707 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5708 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5709
5710 if (!validation_texture_) {
5711 GLint bound_texture;
5712 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5713
5714 // Create additional resources needed for the verification.
5715 glGenTextures(1, &validation_texture_);
5716 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5717 glGenFramebuffersEXT(1, &validation_fbo_);
5718
5719 // Texture only needs to be 1x1.
5720 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5721 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5722 GL_UNSIGNED_BYTE, NULL);
5723
5724 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5725 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5726 GL_TEXTURE_2D, validation_texture_, 0);
5727
5728 glBindTexture(GL_TEXTURE_2D, bound_texture);
5729 }
5730
5731 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5732 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5733 GL_RENDERBUFFER, renderbuffer);
5734
5735 // Cache current state and reset it to the values we require.
5736 GLboolean scissor_enabled = false;
5737 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5738 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455739 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]4a4c18b2013-09-13 22:50:105740
[email protected]454157e2014-05-03 02:49:455741 GLboolean color_mask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
[email protected]4a4c18b2013-09-13 22:50:105742 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
[email protected]454157e2014-05-03 02:49:455743 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
[email protected]4a4c18b2013-09-13 22:50:105744
5745 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5746 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5747 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5748
5749 // Clear the buffer to the desired key color.
5750 glClear(GL_COLOR_BUFFER_BIT);
5751
5752 // Blit from the multisample buffer to a standard texture.
5753 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5754 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5755
[email protected]f42f05b2013-11-15 21:46:185756 BlitFramebufferHelper(
5757 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105758
5759 // Read a pixel from the buffer.
5760 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5761
5762 unsigned char pixel[3] = {0, 0, 0};
5763 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5764
5765 // Detach the renderbuffer.
5766 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5767 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5768 GL_RENDERBUFFER, 0);
5769
5770 // Restore cached state.
5771 if (scissor_enabled)
[email protected]454157e2014-05-03 02:49:455772 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, true);
[email protected]4a4c18b2013-09-13 22:50:105773
[email protected]454157e2014-05-03 02:49:455774 state_.SetDeviceColorMask(
5775 color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
[email protected]4a4c18b2013-09-13 22:50:105776 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5777 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5778 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5779
5780 // Return true if the pixel matched the desired key color.
5781 return (pixel[0] == 0xFF &&
5782 pixel[1] == 0x00 &&
5783 pixel[2] == 0xFF);
5784}
5785
[email protected]36cef8ce2010-03-16 07:34:455786void GLES2DecoderImpl::DoRenderbufferStorage(
5787 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355788 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205789 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5790 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515791 LOCAL_SET_GL_ERROR(
5792 GL_INVALID_OPERATION,
5793 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455794 return;
5795 }
[email protected]876f6fee2010-08-02 23:10:325796
[email protected]84afefa2011-10-19 21:45:535797 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5798 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515799 LOCAL_SET_GL_ERROR(
5800 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535801 return;
5802 }
5803
[email protected]7989c9e2013-01-23 06:39:265804 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235805 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5806 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515807 LOCAL_SET_GL_ERROR(
5808 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265809 return;
5810 }
5811
5812 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515813 LOCAL_SET_GL_ERROR(
5814 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265815 return;
[email protected]b71f52c2010-06-18 22:20:205816 }
[email protected]876f6fee2010-08-02 23:10:325817
[email protected]8875a5f2014-06-27 08:33:475818 EnsureRenderbufferBound();
[email protected]ab09b612013-03-11 22:11:515819 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265820 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:235821 target,
5822 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5823 internalformat),
5824 width,
5825 height);
[email protected]ab09b612013-03-11 22:11:515826 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265827 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515828 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5829 // we could just mark those framebuffers as not complete.
5830 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205831 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265832 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265833 }
[email protected]36cef8ce2010-03-16 07:34:455834}
5835
[email protected]df37b9932013-03-08 05:21:425836void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385837 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425838 Program* program = GetProgramInfoNotShader(
5839 program_id, "glLinkProgram");
5840 if (!program) {
[email protected]a93bb842010-02-16 23:03:475841 return;
5842 }
[email protected]05afda12011-01-20 00:17:345843
[email protected]df37b9932013-03-08 05:21:425844 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]df37b9932013-03-08 05:21:425845 if (program->Link(shader_manager(),
[email protected]008401532014-02-07 00:10:505846 workarounds().count_all_in_varyings_packing ?
5847 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:115848 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425849 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:185850 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:425851 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:185852 if (workarounds().clear_uniforms_before_first_program_use)
5853 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545854 }
5855 }
vmiura8266ca72014-09-09 21:37:005856
5857 // LinkProgram can be very slow. Exit command processing to allow for
5858 // context preemption and GPU watchdog checks.
5859 ExitCommandProcessingEarly();
[email protected]07f54fcc2009-12-22 02:46:305860};
5861
zmobcb3fdd62014-12-11 00:49:035862void GLES2DecoderImpl::DoSamplerParameterfv(
5863 GLuint sampler, GLenum pname, const GLfloat* params) {
5864 DCHECK(params);
5865 glSamplerParameterf(sampler, pname, params[0]);
5866}
5867
5868void GLES2DecoderImpl::DoSamplerParameteriv(
5869 GLuint sampler, GLenum pname, const GLint* params) {
5870 DCHECK(params);
5871 glSamplerParameteri(sampler, pname, params[0]);
5872}
5873
[email protected]3916c97e2010-02-25 03:20:505874void GLES2DecoderImpl::DoTexParameterf(
5875 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445876 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5877 &state_, target);
[email protected]02965c22013-03-09 02:40:075878 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515879 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245880 return;
[email protected]07f54fcc2009-12-22 02:46:305881 }
[email protected]cbb22e42011-05-12 23:36:245882
[email protected]737191ee72014-03-09 08:02:425883 texture_manager()->SetParameterf(
5884 "glTexParameterf", GetErrorState(), texture, pname, param);
[email protected]07f54fcc2009-12-22 02:46:305885}
5886
[email protected]3916c97e2010-02-25 03:20:505887void GLES2DecoderImpl::DoTexParameteri(
5888 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445889 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5890 &state_, target);
[email protected]02965c22013-03-09 02:40:075891 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515892 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245893 return;
[email protected]3916c97e2010-02-25 03:20:505894 }
[email protected]cbb22e42011-05-12 23:36:245895
[email protected]737191ee72014-03-09 08:02:425896 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505897 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505898}
5899
5900void GLES2DecoderImpl::DoTexParameterfv(
5901 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445902 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5903 &state_, target);
[email protected]02965c22013-03-09 02:40:075904 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515905 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245906 return;
[email protected]3916c97e2010-02-25 03:20:505907 }
[email protected]cbb22e42011-05-12 23:36:245908
[email protected]737191ee72014-03-09 08:02:425909 texture_manager()->SetParameterf(
5910 "glTexParameterfv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505911}
5912
5913void GLES2DecoderImpl::DoTexParameteriv(
5914 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445915 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5916 &state_, target);
[email protected]02965c22013-03-09 02:40:075917 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515918 LOCAL_SET_GL_ERROR(
5919 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245920 return;
[email protected]3916c97e2010-02-25 03:20:505921 }
[email protected]cbb22e42011-05-12 23:36:245922
[email protected]737191ee72014-03-09 08:02:425923 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505924 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505925}
5926
orglofchcad5a6742014-11-07 19:51:125927bool GLES2DecoderImpl::CheckCurrentValuebuffer(const char* function_name) {
5928 if (!state_.bound_valuebuffer.get()) {
5929 // There is no valuebuffer bound
5930 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5931 "no valuebuffer in use");
5932 return false;
5933 }
5934 return true;
5935}
5936
5937bool GLES2DecoderImpl::CheckCurrentValuebufferForSubscription(
5938 GLenum subscription,
5939 const char* function_name) {
5940 if (!CheckCurrentValuebuffer(function_name)) {
5941 return false;
5942 }
5943 if (!state_.bound_valuebuffer.get()->IsSubscribed(subscription)) {
5944 // The valuebuffer is not subscribed to the target
5945 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5946 "valuebuffer is not subscribed");
5947 return false;
5948 }
5949 return true;
5950}
5951
5952bool GLES2DecoderImpl::CheckSubscriptionTarget(GLint location,
5953 GLenum subscription,
5954 const char* function_name) {
5955 if (!CheckCurrentProgramForUniform(location, function_name)) {
5956 return false;
5957 }
5958 GLint real_location = -1;
5959 GLint array_index = -1;
5960 const Program::UniformInfo* info =
5961 state_.current_program->GetUniformInfoByFakeLocation(
5962 location, &real_location, &array_index);
5963 if (!info) {
5964 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "unknown location");
5965 return false;
5966 }
5967 if ((ValuebufferManager::ApiTypeForSubscriptionTarget(subscription) &
5968 info->accepts_api_type) == 0) {
5969 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5970 "wrong type for subscription");
5971 return false;
5972 }
5973 return true;
5974}
5975
[email protected]939e7362010-05-13 20:49:105976bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115977 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435978 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515979 LOCAL_SET_GL_ERROR(
5980 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435981 return false;
[email protected]939e7362010-05-13 20:49:105982 }
[email protected]e259eb412012-10-13 05:47:245983 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515984 LOCAL_SET_GL_ERROR(
5985 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105986 return false;
5987 }
5988 return true;
5989}
5990
5991bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5992 GLint location, const char* function_name) {
5993 if (!CheckCurrentProgram(function_name)) {
5994 return false;
5995 }
5996 return location != -1;
5997}
5998
zmof9a81360f2014-10-17 00:06:145999bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() {
6000 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
6001 if (!framebuffer)
6002 return false;
6003 const Framebuffer::Attachment* attachment =
6004 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
6005 if (!attachment)
6006 return false;
6007
6008 DCHECK(state_.current_program.get());
6009 const Program::SamplerIndices& sampler_indices =
6010 state_.current_program->sampler_indices();
6011 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
6012 const Program::UniformInfo* uniform_info =
6013 state_.current_program->GetUniformInfo(sampler_indices[ii]);
6014 DCHECK(uniform_info);
6015 if (uniform_info->type != GL_SAMPLER_2D)
6016 continue;
6017 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6018 GLuint texture_unit_index = uniform_info->texture_units[jj];
6019 if (texture_unit_index >= state_.texture_units.size())
6020 continue;
6021 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
6022 TextureRef* texture_ref =
6023 texture_unit.GetInfoForSamplerType(GL_SAMPLER_2D).get();
6024 if (attachment->IsTexture(texture_ref))
6025 return true;
6026 }
6027 }
6028 return false;
6029}
6030
orglofchcad5a6742014-11-07 19:51:126031bool GLES2DecoderImpl::CheckUniformForApiType(
6032 const Program::UniformInfo* info,
6033 const char* function_name,
6034 Program::UniformApiType api_type) {
6035 DCHECK(info);
6036 if ((api_type & info->accepts_api_type) == 0) {
6037 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6038 "wrong uniform function for type");
6039 return false;
6040 }
6041 return true;
6042}
6043
[email protected]43c2f1f2011-03-25 18:35:366044bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]9b1f1b52014-03-12 10:40:136045 GLint fake_location,
6046 const char* function_name,
6047 Program::UniformApiType api_type,
6048 GLint* real_location,
6049 GLenum* type,
6050 GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:366051 DCHECK(type);
6052 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:126053 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:526054
[email protected]1b0a6752012-02-22 03:44:126055 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:106056 return false;
6057 }
[email protected]43c2f1f2011-03-25 18:35:366058 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:356059 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:246060 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:126061 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:366062 if (!info) {
[email protected]ab09b612013-03-11 22:11:516063 LOCAL_SET_GL_ERROR(
6064 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:106065 return false;
6066 }
orglofchcad5a6742014-11-07 19:51:126067 if (!CheckUniformForApiType(info, function_name, api_type)) {
[email protected]476ccb72012-12-06 15:52:526068 return false;
6069 }
[email protected]43c2f1f2011-03-25 18:35:366070 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:516071 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436072 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:366073 return false;
6074 }
6075 *count = std::min(info->size - array_index, *count);
6076 if (*count <= 0) {
6077 return false;
6078 }
6079 *type = info->type;
[email protected]939e7362010-05-13 20:49:106080 return true;
6081}
6082
[email protected]1b0a6752012-02-22 03:44:126083void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
6084 GLenum type = 0;
6085 GLsizei count = 1;
6086 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136087 if (!PrepForSetUniformByLocation(fake_location,
6088 "glUniform1i",
6089 Program::kUniform1i,
6090 &real_location,
6091 &type,
6092 &count)) {
[email protected]3916c97e2010-02-25 03:20:506093 return;
6094 }
[email protected]e259eb412012-10-13 05:47:246095 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026096 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:516097 LOCAL_SET_GL_ERROR(
6098 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466099 return;
6100 }
[email protected]1b0a6752012-02-22 03:44:126101 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:506102}
6103
6104void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:126105 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:366106 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126107 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136108 if (!PrepForSetUniformByLocation(fake_location,
6109 "glUniform1iv",
6110 Program::kUniform1i,
6111 &real_location,
6112 &type,
6113 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366114 return;
6115 }
[email protected]74727112012-06-13 21:18:086116 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
6117 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:246118 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026119 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:516120 LOCAL_SET_GL_ERROR(
6121 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466122 return;
6123 }
[email protected]43c2f1f2011-03-25 18:35:366124 }
[email protected]1b0a6752012-02-22 03:44:126125 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:506126}
6127
[email protected]939e7362010-05-13 20:49:106128void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:126129 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366130 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126131 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136132 if (!PrepForSetUniformByLocation(fake_location,
6133 "glUniform1fv",
6134 Program::kUniform1f,
6135 &real_location,
6136 &type,
6137 &count)) {
[email protected]939e7362010-05-13 20:49:106138 return;
6139 }
6140 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:556141 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:106142 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:536143 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106144 }
[email protected]1b0a6752012-02-22 03:44:126145 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106146 } else {
[email protected]1b0a6752012-02-22 03:44:126147 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106148 }
6149}
6150
6151void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:126152 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366153 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126154 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136155 if (!PrepForSetUniformByLocation(fake_location,
6156 "glUniform2fv",
6157 Program::kUniform2f,
6158 &real_location,
6159 &type,
6160 &count)) {
[email protected]939e7362010-05-13 20:49:106161 return;
6162 }
6163 if (type == GL_BOOL_VEC2) {
6164 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:556165 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106166 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536167 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106168 }
[email protected]1b0a6752012-02-22 03:44:126169 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106170 } else {
[email protected]1b0a6752012-02-22 03:44:126171 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106172 }
6173}
6174
6175void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:126176 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366177 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126178 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136179 if (!PrepForSetUniformByLocation(fake_location,
6180 "glUniform3fv",
6181 Program::kUniform3f,
6182 &real_location,
6183 &type,
6184 &count)) {
[email protected]939e7362010-05-13 20:49:106185 return;
6186 }
6187 if (type == GL_BOOL_VEC3) {
6188 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:556189 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106190 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536191 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106192 }
[email protected]1b0a6752012-02-22 03:44:126193 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106194 } else {
[email protected]1b0a6752012-02-22 03:44:126195 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106196 }
6197}
6198
6199void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:126200 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366201 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126202 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136203 if (!PrepForSetUniformByLocation(fake_location,
6204 "glUniform4fv",
6205 Program::kUniform4f,
6206 &real_location,
6207 &type,
6208 &count)) {
[email protected]939e7362010-05-13 20:49:106209 return;
6210 }
6211 if (type == GL_BOOL_VEC4) {
6212 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:556213 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106214 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536215 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106216 }
[email protected]1b0a6752012-02-22 03:44:126217 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106218 } else {
[email protected]1b0a6752012-02-22 03:44:126219 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106220 }
6221}
6222
[email protected]43c2f1f2011-03-25 18:35:366223void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:126224 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366225 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126226 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136227 if (!PrepForSetUniformByLocation(fake_location,
6228 "glUniform2iv",
6229 Program::kUniform2i,
6230 &real_location,
6231 &type,
6232 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366233 return;
6234 }
[email protected]1b0a6752012-02-22 03:44:126235 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366236}
6237
6238void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:126239 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366240 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126241 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136242 if (!PrepForSetUniformByLocation(fake_location,
6243 "glUniform3iv",
6244 Program::kUniform3i,
6245 &real_location,
6246 &type,
6247 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366248 return;
6249 }
[email protected]1b0a6752012-02-22 03:44:126250 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366251}
6252
6253void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:126254 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366255 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126256 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136257 if (!PrepForSetUniformByLocation(fake_location,
6258 "glUniform4iv",
6259 Program::kUniform4i,
6260 &real_location,
6261 &type,
6262 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366263 return;
6264 }
[email protected]1b0a6752012-02-22 03:44:126265 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366266}
6267
6268void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:126269 GLint fake_location, GLsizei count, GLboolean transpose,
6270 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366271 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126272 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136273 if (!PrepForSetUniformByLocation(fake_location,
6274 "glUniformMatrix2fv",
6275 Program::kUniformMatrix2f,
6276 &real_location,
6277 &type,
6278 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366279 return;
6280 }
[email protected]1b0a6752012-02-22 03:44:126281 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366282}
6283
6284void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:126285 GLint fake_location, GLsizei count, GLboolean transpose,
6286 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366287 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126288 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136289 if (!PrepForSetUniformByLocation(fake_location,
6290 "glUniformMatrix3fv",
6291 Program::kUniformMatrix3f,
6292 &real_location,
6293 &type,
6294 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366295 return;
6296 }
[email protected]1b0a6752012-02-22 03:44:126297 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366298}
6299
6300void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:126301 GLint fake_location, GLsizei count, GLboolean transpose,
6302 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366303 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126304 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136305 if (!PrepForSetUniformByLocation(fake_location,
6306 "glUniformMatrix4fv",
6307 Program::kUniformMatrix4f,
6308 &real_location,
6309 &type,
6310 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366311 return;
6312 }
[email protected]1b0a6752012-02-22 03:44:126313 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366314}
6315
[email protected]df37b9932013-03-08 05:21:426316void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:036317 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:426318 Program* program = NULL;
6319 if (program_id) {
6320 program = GetProgramInfoNotShader(program_id, "glUseProgram");
6321 if (!program) {
[email protected]ae51d192010-04-27 00:48:036322 return;
6323 }
[email protected]df37b9932013-03-08 05:21:426324 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:506325 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:516326 LOCAL_SET_GL_ERROR(
6327 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:506328 return;
6329 }
[email protected]df37b9932013-03-08 05:21:426330 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:506331 }
[email protected]7cd76fd2013-06-02 21:11:116332 if (state_.current_program.get()) {
6333 program_manager()->UnuseProgram(shader_manager(),
6334 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:146335 }
[email protected]df37b9932013-03-08 05:21:426336 state_.current_program = program;
6337 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:546338 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:116339 if (state_.current_program.get()) {
6340 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:186341 if (workarounds().clear_uniforms_before_first_program_use)
6342 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:146343 }
[email protected]3916c97e2010-02-25 03:20:506344}
6345
[email protected]ab09b612013-03-11 22:11:516346void GLES2DecoderImpl::RenderWarning(
6347 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:326348 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016349}
6350
[email protected]ab09b612013-03-11 22:11:516351void GLES2DecoderImpl::PerformanceWarning(
6352 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:506353 logger_.LogMessage(filename, line,
6354 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016355}
6356
[email protected]91c94eb2013-10-22 10:32:546357void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
6358 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546359 // Image is already in use if texture is attached to a framebuffer.
6360 if (texture && !texture->IsAttachedToFramebuffer()) {
6361 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6362 if (image) {
6363 ScopedGLErrorSuppressor suppressor(
6364 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
6365 GetErrorState());
6366 glBindTexture(textarget, texture->service_id());
6367 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026368 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546369 }
6370 }
6371}
6372
6373void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
6374 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546375 // Image is still in use if texture is attached to a framebuffer.
6376 if (texture && !texture->IsAttachedToFramebuffer()) {
6377 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6378 if (image) {
6379 ScopedGLErrorSuppressor suppressor(
6380 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6381 GetErrorState());
6382 glBindTexture(textarget, texture->service_id());
6383 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026384 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546385 }
6386 }
6387}
6388
[email protected]e56131d22013-07-28 16:14:116389bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:116390 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:546391 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:556392 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:116393 return true;
[email protected]ef526492010-06-02 23:12:256394 }
[email protected]e2367b42013-05-31 03:37:216395
[email protected]ef526492010-06-02 23:12:256396 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356397 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246398 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506399 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356400 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246401 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506402 DCHECK(uniform_info);
6403 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6404 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026405 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246406 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546407 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366408 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546409 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6410 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256411 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506412 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6413 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546414 textarget,
[email protected]00f893d2010-08-24 18:55:496415 texture_manager()->black_texture_id(uniform_info->type));
dongseong.hwang7d87d722015-01-14 20:02:406416 if (!texture_ref) {
6417 LOCAL_RENDER_WARNING(
6418 std::string("there is no texture bound to the unit ") +
6419 base::IntToString(texture_unit_index));
6420 } else {
6421 LOCAL_RENDER_WARNING(
6422 std::string("texture bound to texture unit ") +
6423 base::IntToString(texture_unit_index) +
6424 " is not renderable. It maybe non-power-of-2 and have"
6425 " incompatible texture filtering.");
6426 }
[email protected]91c94eb2013-10-22 10:32:546427 continue;
[email protected]3916c97e2010-02-25 03:20:506428 }
[email protected]91c94eb2013-10-22 10:32:546429
[email protected]4e7b89202014-01-28 01:44:066430 if (textarget != GL_TEXTURE_CUBE_MAP) {
6431 Texture* texture = texture_ref->texture();
6432 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6433 if (image && !texture->IsAttachedToFramebuffer()) {
6434 ScopedGLErrorSuppressor suppressor(
6435 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6436 textures_set = true;
6437 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6438 image->WillUseTexImage();
6439 continue;
6440 }
[email protected]91c94eb2013-10-22 10:32:546441 }
[email protected]3916c97e2010-02-25 03:20:506442 }
6443 // else: should this be an error?
6444 }
6445 }
[email protected]e56131d22013-07-28 16:14:116446 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506447}
6448
[email protected]91c94eb2013-10-22 10:32:546449void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116450 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356451 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116452 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506453 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356454 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246455 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506456 DCHECK(uniform_info);
6457 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6458 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026459 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246460 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116461 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546462 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496463 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506464 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496465 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116466 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6467 ? texture_unit.bound_texture_2d.get()
6468 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506469 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496470 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546471 continue;
6472 }
6473
[email protected]4e7b89202014-01-28 01:44:066474 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6475 Texture* texture = texture_ref->texture();
6476 gfx::GLImage* image =
6477 texture->GetLevelImage(texture_unit.bind_target, 0);
6478 if (image && !texture->IsAttachedToFramebuffer()) {
6479 ScopedGLErrorSuppressor suppressor(
6480 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6481 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6482 image->DidUseTexImage();
6483 continue;
6484 }
[email protected]3916c97e2010-02-25 03:20:506485 }
6486 }
6487 }
6488 }
6489 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246490 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306491}
6492
[email protected]0d6bfdc2011-11-02 01:32:206493bool GLES2DecoderImpl::ClearUnclearedTextures() {
6494 // Only check if there are some uncleared textures.
6495 if (!texture_manager()->HaveUnsafeTextures()) {
6496 return true;
6497 }
6498
6499 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116500 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356501 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116502 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206503 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356504 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246505 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206506 DCHECK(uniform_info);
6507 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6508 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026509 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246510 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496511 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366512 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496513 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6514 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206515 return false;
6516 }
6517 }
6518 }
6519 }
6520 }
6521 }
6522 return true;
6523}
6524
[email protected]c6aef902012-02-14 03:31:426525bool GLES2DecoderImpl::IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:106526 const char* function_name, GLuint max_vertex_accessed, bool instanced,
6527 GLsizei primcount) {
6528 DCHECK(instanced || primcount == 1);
6529
[email protected]689fa1c52010-06-09 18:35:036530 // NOTE: We specifically do not check current_program->IsValid() because
6531 // it could never be invalid since glUseProgram would have failed. While
6532 // glLinkProgram could later mark the program as invalid the previous
6533 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116534 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506535 // The program does not exist.
6536 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516537 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506538 return false;
6539 }
[email protected]c6aef902012-02-14 03:31:426540
zmof9a81360f2014-10-17 00:06:146541 if (CheckDrawingFeedbackLoops()) {
6542 LOCAL_SET_GL_ERROR(
6543 GL_INVALID_OPERATION, function_name,
6544 "Source and destination textures of the draw are the same.");
6545 return false;
6546 }
6547
[email protected]7cd76fd2013-06-02 21:11:116548 return state_.vertex_attrib_manager
6549 ->ValidateBindings(function_name,
6550 this,
6551 feature_info_.get(),
6552 state_.current_program.get(),
6553 max_vertex_accessed,
[email protected]ac6904d62014-07-30 12:00:106554 instanced,
[email protected]7cd76fd2013-06-02 21:11:116555 primcount);
[email protected]b1122982010-05-17 23:04:246556}
6557
[email protected]c13e1da62011-09-09 21:48:306558bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436559 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306560 DCHECK(simulated);
6561 *simulated = false;
6562
[email protected]876f6fee2010-08-02 23:10:326563 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:306564 return true;
[email protected]876f6fee2010-08-02 23:10:326565
[email protected]ac77603c72013-03-08 13:52:066566 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356567 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246568 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246569 bool attrib_0_used =
6570 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066571 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306572 return true;
[email protected]b1122982010-05-17 23:04:246573 }
6574
[email protected]b1122982010-05-17 23:04:246575 // Make a buffer with a single repeated vec4 value enough to
6576 // simulate the constant value that is supposed to be here.
6577 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306578 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476579 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306580
6581 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476582 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306583 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516584 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306585 return false;
6586 }
6587
[email protected]ab09b612013-03-11 22:11:516588 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016589 "Attribute 0 is disabled. This has signficant performance penalty");
6590
[email protected]ab09b612013-03-11 22:11:516591 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306592 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6593
[email protected]8f0b86c2f2012-04-10 05:48:286594 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6595 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496596 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306597 GLenum error = glGetError();
6598 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516599 LOCAL_SET_GL_ERROR(
6600 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306601 return false;
6602 }
[email protected]fc753442011-02-04 19:49:496603 }
[email protected]af6380962012-11-29 23:24:136604
6605 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286606 if (new_buffer ||
6607 (attrib_0_used &&
6608 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136609 (value.v[0] != attrib_0_value_.v[0] ||
6610 value.v[1] != attrib_0_value_.v[1] ||
6611 value.v[2] != attrib_0_value_.v[2] ||
6612 value.v[3] != attrib_0_value_.v[3])))) {
6613 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496614 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6615 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136616 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246617 attrib_0_size_ = size_needed;
6618 }
6619
6620 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6621
[email protected]ac77603c72013-03-08 13:52:066622 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426623 glVertexAttribDivisorANGLE(0, 0);
6624
[email protected]c13e1da62011-09-09 21:48:306625 *simulated = true;
[email protected]b1122982010-05-17 23:04:246626 return true;
[email protected]b1122982010-05-17 23:04:246627}
6628
[email protected]3fc38e22014-05-30 00:13:236629void GLES2DecoderImpl::RestoreStateForAttrib(
6630 GLuint attrib_index, bool restore_array_binding) {
[email protected]ac77603c72013-03-08 13:52:066631 const VertexAttrib* attrib =
6632 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
[email protected]3fc38e22014-05-30 00:13:236633 if (restore_array_binding) {
6634 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6635 Buffer* buffer = attrib->buffer();
6636 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
6637 glVertexAttribPointer(
6638 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6639 attrib->gl_stride(), ptr);
6640 }
[email protected]ac77603c72013-03-08 13:52:066641 if (attrib->divisor())
6642 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246643 glBindBuffer(
[email protected]3fc38e22014-05-30 00:13:236644 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
6645 state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:286646
[email protected]265f8992012-07-20 01:03:146647 // Never touch vertex attribute 0's state (in particular, never
6648 // disable it) when running on desktop GL because it will never be
6649 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066650 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146651 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066652 if (attrib->enabled()) {
6653 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146654 } else {
[email protected]ac77603c72013-03-08 13:52:066655 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146656 }
[email protected]43410e92012-04-20 17:06:286657 }
[email protected]b1122982010-05-17 23:04:246658}
[email protected]07f54fcc2009-12-22 02:46:306659
[email protected]8fbedc02010-11-18 18:43:406660bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436661 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426662 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406663 DCHECK(simulated);
6664 *simulated = false;
6665 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6666 return true;
6667
[email protected]e259eb412012-10-13 05:47:246668 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406669 return true;
6670 }
6671
[email protected]ab09b612013-03-11 22:11:516672 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016673 "GL_FIXED attributes have a signficant performance penalty");
6674
[email protected]8fbedc02010-11-18 18:43:406675 // NOTE: we could be smart and try to check if a buffer is used
6676 // twice in 2 different attribs, find the overlapping parts and therefore
6677 // duplicate the minimum amount of data but this whole code path is not meant
6678 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6679 // tests so we just add to the buffer attrib used.
6680
[email protected]c13e1da62011-09-09 21:48:306681 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066682 const VertexAttribManager::VertexAttribList& enabled_attribs =
6683 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6684 for (VertexAttribManager::VertexAttribList::const_iterator it =
6685 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6686 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356687 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066688 state_.current_program->GetAttribInfoByLocation(attrib->index());
6689 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6690 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426691 GLuint num_vertices = max_accessed + 1;
6692 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516693 LOCAL_SET_GL_ERROR(
6694 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426695 return false;
6696 }
[email protected]8fbedc02010-11-18 18:43:406697 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066698 attrib->CanAccess(max_accessed) &&
6699 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476700 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066701 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476702 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516703 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436704 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406705 return false;
6706 }
6707 }
6708 }
6709
[email protected]3aad1a32012-09-07 20:54:476710 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6711 uint32 size_needed = 0;
6712 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306713 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516714 LOCAL_SET_GL_ERROR(
6715 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406716 return false;
6717 }
6718
[email protected]ab09b612013-03-11 22:11:516719 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406720
6721 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306722 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406723 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306724 GLenum error = glGetError();
6725 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516726 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436727 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306728 return false;
6729 }
[email protected]8fbedc02010-11-18 18:43:406730 }
6731
6732 // Copy the elements and convert to float
6733 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066734 for (VertexAttribManager::VertexAttribList::const_iterator it =
6735 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6736 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356737 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066738 state_.current_program->GetAttribInfoByLocation(attrib->index());
6739 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426740 max_vertex_accessed);
6741 GLuint num_vertices = max_accessed + 1;
6742 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516743 LOCAL_SET_GL_ERROR(
6744 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426745 return false;
6746 }
[email protected]8fbedc02010-11-18 18:43:406747 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066748 attrib->CanAccess(max_accessed) &&
6749 attrib->type() == GL_FIXED) {
penghuang5a3210b2014-10-29 18:24:366750 int num_elements = attrib->size() * num_vertices;
6751 const int src_size = num_elements * sizeof(int32);
6752 const int dst_size = num_elements * sizeof(float);
6753 scoped_ptr<float[]> data(new float[num_elements]);
[email protected]8fbedc02010-11-18 18:43:406754 const int32* src = reinterpret_cast<const int32 *>(
penghuang5a3210b2014-10-29 18:24:366755 attrib->buffer()->GetRange(attrib->offset(), src_size));
[email protected]8fbedc02010-11-18 18:43:406756 const int32* end = src + num_elements;
6757 float* dst = data.get();
6758 while (src != end) {
6759 *dst++ = static_cast<float>(*src++) / 65536.0f;
6760 }
penghuang5a3210b2014-10-29 18:24:366761 glBufferSubData(GL_ARRAY_BUFFER, offset, dst_size, data.get());
[email protected]8fbedc02010-11-18 18:43:406762 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066763 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406764 reinterpret_cast<GLvoid*>(offset));
penghuang5a3210b2014-10-29 18:24:366765 offset += dst_size;
[email protected]8fbedc02010-11-18 18:43:406766 }
6767 }
6768 *simulated = true;
6769 return true;
6770}
6771
6772void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6773 // There's no need to call glVertexAttribPointer because we shadow all the
6774 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246775 glBindBuffer(
6776 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116777 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6778 : 0);
[email protected]8fbedc02010-11-18 18:43:406779}
6780
[email protected]ad84a3a2012-06-08 21:42:436781error::Error GLES2DecoderImpl::DoDrawArrays(
6782 const char* function_name,
6783 bool instanced,
6784 GLenum mode,
6785 GLint first,
6786 GLsizei count,
6787 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226788 error::Error error = WillAccessBoundFramebufferForDraw();
6789 if (error != error::kNoError)
6790 return error;
[email protected]38d139d2011-07-14 00:38:436791 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516792 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436793 return error::kNoError;
6794 }
6795 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516796 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436797 return error::kNoError;
6798 }
[email protected]c6aef902012-02-14 03:31:426799 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516800 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426801 return error::kNoError;
6802 }
[email protected]ad84a3a2012-06-08 21:42:436803 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436804 return error::kNoError;
6805 }
6806 // We have to check this here because the prototype for glDrawArrays
6807 // is GLint not GLsizei.
6808 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516809 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436810 return error::kNoError;
6811 }
6812
[email protected]ac6904d62014-07-30 12:00:106813 if (count == 0 || primcount == 0) {
[email protected]ab09b612013-03-11 22:11:516814 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436815 return error::kNoError;
6816 }
6817
6818 GLuint max_vertex_accessed = first + count - 1;
[email protected]ac6904d62014-07-30 12:00:106819 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206820 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516821 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206822 return error::kNoError;
6823 }
[email protected]c13e1da62011-09-09 21:48:306824 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436825 if (!SimulateAttrib0(
6826 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306827 return error::kNoError;
6828 }
[email protected]38d139d2011-07-14 00:38:436829 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436830 if (SimulateFixedAttribs(
6831 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6832 primcount)) {
[email protected]e56131d22013-07-28 16:14:116833 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436834 ApplyDirtyState();
[email protected]00c2cf92014-03-14 00:08:376835 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426836 if (!instanced) {
6837 glDrawArrays(mode, first, count);
6838 } else {
6839 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6840 }
[email protected]38d139d2011-07-14 00:38:436841 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546842 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436843 }
6844 if (simulated_fixed_attribs) {
6845 RestoreStateForSimulatedFixedAttribs();
6846 }
6847 }
6848 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236849 // We don't have to restore attrib 0 generic data at the end of this
6850 // function even if it is simulated. This is because we will simulate
6851 // it in each draw call, and attrib 0 generic data queries use cached
6852 // values instead of passing down to the underlying driver.
6853 RestoreStateForAttrib(0, false);
[email protected]38d139d2011-07-14 00:38:436854 }
[email protected]38d139d2011-07-14 00:38:436855 }
6856 return error::kNoError;
6857}
6858
vmiuracd108592014-09-08 14:36:346859error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size,
6860 const void* cmd_data) {
6861 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436862 return DoDrawArrays("glDrawArrays",
6863 false,
[email protected]c6aef902012-02-14 03:31:426864 static_cast<GLenum>(c.mode),
6865 static_cast<GLint>(c.first),
6866 static_cast<GLsizei>(c.count),
[email protected]ac6904d62014-07-30 12:00:106867 1);
[email protected]c6aef902012-02-14 03:31:426868}
6869
6870error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
vmiuracd108592014-09-08 14:36:346871 uint32 immediate_data_size,
6872 const void* cmd_data) {
6873 const gles2::cmds::DrawArraysInstancedANGLE& c =
6874 *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156875 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516876 LOCAL_SET_GL_ERROR(
6877 GL_INVALID_OPERATION,
6878 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426879 return error::kNoError;
6880 }
[email protected]ad84a3a2012-06-08 21:42:436881 return DoDrawArrays("glDrawArraysIntancedANGLE",
6882 true,
[email protected]c6aef902012-02-14 03:31:426883 static_cast<GLenum>(c.mode),
6884 static_cast<GLint>(c.first),
6885 static_cast<GLsizei>(c.count),
6886 static_cast<GLsizei>(c.primcount));
6887}
6888
[email protected]ad84a3a2012-06-08 21:42:436889error::Error GLES2DecoderImpl::DoDrawElements(
6890 const char* function_name,
6891 bool instanced,
6892 GLenum mode,
6893 GLsizei count,
6894 GLenum type,
6895 int32 offset,
6896 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226897 error::Error error = WillAccessBoundFramebufferForDraw();
6898 if (error != error::kNoError)
6899 return error;
[email protected]e259eb412012-10-13 05:47:246900 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516901 LOCAL_SET_GL_ERROR(
6902 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296903 return error::kNoError;
6904 }
6905
[email protected]8eee29c2010-04-29 03:38:296906 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516907 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296908 return error::kNoError;
6909 }
6910 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516911 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296912 return error::kNoError;
6913 }
[email protected]9438b012010-06-15 22:55:056914 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516915 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296916 return error::kNoError;
6917 }
[email protected]9438b012010-06-15 22:55:056918 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516919 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296920 return error::kNoError;
6921 }
[email protected]c6aef902012-02-14 03:31:426922 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516923 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426924 return error::kNoError;
6925 }
[email protected]8eee29c2010-04-29 03:38:296926
[email protected]ad84a3a2012-06-08 21:42:436927 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276928 return error::kNoError;
6929 }
6930
[email protected]ac6904d62014-07-30 12:00:106931 if (count == 0 || primcount == 0) {
[email protected]6c788fb72010-08-26 02:16:316932 return error::kNoError;
6933 }
6934
[email protected]8eee29c2010-04-29 03:38:296935 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086936 Buffer* element_array_buffer =
6937 state_.vertex_attrib_manager->element_array_buffer();
6938
6939 if (!element_array_buffer->GetMaxValueForRange(
6940 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516941 LOCAL_SET_GL_ERROR(
6942 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296943 return error::kNoError;
6944 }
6945
[email protected]ac6904d62014-07-30 12:00:106946 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206947 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516948 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206949 return error::kNoError;
6950 }
[email protected]c13e1da62011-09-09 21:48:306951 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436952 if (!SimulateAttrib0(
6953 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306954 return error::kNoError;
6955 }
[email protected]8fbedc02010-11-18 18:43:406956 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436957 if (SimulateFixedAttribs(
6958 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6959 primcount)) {
[email protected]e56131d22013-07-28 16:14:116960 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466961 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086962 // TODO(gman): Refactor to hide these details in BufferManager or
6963 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406964 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086965 bool used_client_side_array = false;
6966 if (element_array_buffer->IsClientSideArray()) {
6967 used_client_side_array = true;
6968 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6969 indices = element_array_buffer->GetRange(offset, 0);
6970 }
6971
[email protected]00c2cf92014-03-14 00:08:376972 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426973 if (!instanced) {
6974 glDrawElements(mode, count, type, indices);
6975 } else {
6976 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6977 }
[email protected]17cfbe0e2013-03-07 01:26:086978
6979 if (used_client_side_array) {
6980 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6981 element_array_buffer->service_id());
6982 }
6983
[email protected]8fbedc02010-11-18 18:43:406984 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546985 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:406986 }
6987 if (simulated_fixed_attribs) {
6988 RestoreStateForSimulatedFixedAttribs();
6989 }
[email protected]ba3176a2009-12-16 18:19:466990 }
[email protected]b1122982010-05-17 23:04:246991 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236992 // We don't have to restore attrib 0 generic data at the end of this
6993 // function even if it is simulated. This is because we will simulate
6994 // it in each draw call, and attrib 0 generic data queries use cached
6995 // values instead of passing down to the underlying driver.
6996 RestoreStateForAttrib(0, false);
[email protected]b1122982010-05-17 23:04:246997 }
[email protected]96449d2c2009-11-25 00:01:326998 }
[email protected]f7a64ee2010-02-01 22:24:146999 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327000}
7001
vmiuracd108592014-09-08 14:36:347002error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size,
7003 const void* cmd_data) {
7004 const gles2::cmds::DrawElements& c =
7005 *static_cast<const gles2::cmds::DrawElements*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:437006 return DoDrawElements("glDrawElements",
7007 false,
[email protected]c6aef902012-02-14 03:31:427008 static_cast<GLenum>(c.mode),
7009 static_cast<GLsizei>(c.count),
7010 static_cast<GLenum>(c.type),
7011 static_cast<int32>(c.index_offset),
[email protected]ac6904d62014-07-30 12:00:107012 1);
[email protected]c6aef902012-02-14 03:31:427013}
7014
7015error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
vmiuracd108592014-09-08 14:36:347016 uint32 immediate_data_size,
7017 const void* cmd_data) {
7018 const gles2::cmds::DrawElementsInstancedANGLE& c =
7019 *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157020 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517021 LOCAL_SET_GL_ERROR(
7022 GL_INVALID_OPERATION,
7023 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:427024 return error::kNoError;
7025 }
[email protected]ad84a3a2012-06-08 21:42:437026 return DoDrawElements("glDrawElementsInstancedANGLE",
7027 true,
[email protected]c6aef902012-02-14 03:31:427028 static_cast<GLenum>(c.mode),
7029 static_cast<GLsizei>(c.count),
7030 static_cast<GLenum>(c.type),
7031 static_cast<int32>(c.index_offset),
7032 static_cast<GLsizei>(c.primcount));
7033}
7034
[email protected]269200b12010-11-18 22:53:067035GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:237036 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
7037 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:077038 Buffer* buffer = GetBuffer(buffer_id);
7039 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:037040 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517041 LOCAL_SET_GL_ERROR(
7042 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:237043 } else {
[email protected]b10492f2013-03-08 05:24:077044 if (!buffer->GetMaxValueForRange(
7045 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:037046 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517047 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:067048 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437049 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:237050 }
7051 }
7052 return max_vertex_accessed;
7053}
7054
zmo1bb3d1d2015-01-21 20:29:437055void GLES2DecoderImpl::DoShaderSource(
7056 GLuint client_id, GLsizei count, const char** data, const GLint* length) {
7057 std::string str;
7058 for (GLsizei ii = 0; ii < count; ++ii) {
dyen7b0b4ba52015-02-04 21:38:067059 if (length && length[ii] > 0)
7060 str.append(data[ii], length[ii]);
7061 else
7062 str.append(data[ii]);
zmo1bb3d1d2015-01-21 20:29:437063 }
[email protected]df37b9932013-03-08 05:21:427064 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
7065 if (!shader) {
zmo1bb3d1d2015-01-21 20:29:437066 return;
[email protected]96449d2c2009-11-25 00:01:327067 }
[email protected]45bf5152010-02-12 00:11:317068 // Note: We don't actually call glShaderSource here. We wait until
dyen7b0b4ba52015-02-04 21:38:067069 // we actually compile the shader.
zmo576a0492014-09-13 01:12:327070 shader->set_source(str);
[email protected]558847a2010-03-24 07:02:547071}
7072
zmo38923562015-01-29 20:17:397073void GLES2DecoderImpl::DoTransformFeedbackVaryings(
7074 GLuint client_program_id, GLsizei count, const char* const* varyings,
7075 GLenum buffer_mode) {
7076 Program* program = GetProgramInfoNotShader(
7077 client_program_id, "glTransformFeedbackVaryings");
7078 if (!program) {
7079 return;
7080 }
7081 glTransformFeedbackVaryings(
7082 program->service_id(), count, varyings, buffer_mode);
7083}
7084
[email protected]ae51d192010-04-27 00:48:037085void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:387086 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:427087 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
7088 if (!shader) {
[email protected]45bf5152010-02-12 00:11:317089 return;
7090 }
dyen0ff9e4402015-02-12 22:27:437091
7092 scoped_refptr<ShaderTranslatorInterface> translator;
[email protected]b1d2dcb2010-05-17 19:24:187093 if (use_shader_translator_) {
dyen0ff9e4402015-02-12 22:27:437094 translator = shader->shader_type() == GL_VERTEX_SHADER ?
7095 vertex_translator_ : fragment_translator_;
[email protected]de17df392010-04-23 21:09:417096 }
[email protected]de17df392010-04-23 21:09:417097
dyen0ff9e4402015-02-12 22:27:437098 const Shader::TranslatedShaderSourceType source_type =
7099 feature_info_->feature_flags().angle_translated_shader_source ?
7100 Shader::kANGLE : Shader::kGL;
7101 shader->RequestCompile(translator, source_type);
vmiura8266ca72014-09-09 21:37:007102}
[email protected]45bf5152010-02-12 00:11:317103
[email protected]ddd968b82010-03-02 00:44:297104void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:427105 GLuint shader_id, GLenum pname, GLint* params) {
7106 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
7107 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:297108 return;
7109 }
dyen0ff9e4402015-02-12 22:27:437110
7111 // Compile now for statuses that require it.
7112 switch (pname) {
7113 case GL_COMPILE_STATUS:
7114 case GL_INFO_LOG_LENGTH:
7115 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
7116 shader->DoCompile();
7117 break;
7118
7119 default:
7120 break;
7121 }
7122
[email protected]8f1ccdac2010-05-19 21:01:487123 switch (pname) {
7124 case GL_SHADER_SOURCE_LENGTH:
zmo576a0492014-09-13 01:12:327125 *params = shader->source().size();
7126 if (*params)
7127 ++(*params);
[email protected]8f1ccdac2010-05-19 21:01:487128 return;
7129 case GL_COMPILE_STATUS:
zmo576a0492014-09-13 01:12:327130 *params = compile_shader_always_succeeds_ ? true : shader->valid();
[email protected]e5186162010-06-14 18:54:417131 return;
[email protected]8f1ccdac2010-05-19 21:01:487132 case GL_INFO_LOG_LENGTH:
zmo576a0492014-09-13 01:12:327133 *params = shader->log_info().size();
7134 if (*params)
7135 ++(*params);
[email protected]e5186162010-06-14 18:54:417136 return;
[email protected]d6a53e42011-10-05 00:09:367137 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
zmo576a0492014-09-13 01:12:327138 *params = shader->translated_source().size();
7139 if (*params)
7140 ++(*params);
[email protected]d6a53e42011-10-05 00:09:367141 return;
[email protected]8f1ccdac2010-05-19 21:01:487142 default:
7143 break;
[email protected]ddd968b82010-03-02 00:44:297144 }
[email protected]df37b9932013-03-08 05:21:427145 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:297146}
7147
vmiuracd108592014-09-08 14:36:347148error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size,
7149 const void* cmd_data) {
7150 const gles2::cmds::GetShaderSource& c =
7151 *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427152 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:037153 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7154 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427155 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
zmo576a0492014-09-13 01:12:327156 if (!shader || shader->source().empty()) {
[email protected]8eee29c2010-04-29 03:38:297157 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:297158 return error::kNoError;
7159 }
zmo576a0492014-09-13 01:12:327160 bucket->SetFromString(shader->source().c_str());
[email protected]ae51d192010-04-27 00:48:037161 return error::kNoError;
7162}
7163
[email protected]d6a53e42011-10-05 00:09:367164error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
7165 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:347166 const void* cmd_data) {
7167 const gles2::cmds::GetTranslatedShaderSourceANGLE& c =
7168 *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>(
7169 cmd_data);
[email protected]df37b9932013-03-08 05:21:427170 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:367171 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7172 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427173 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:207174 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:427175 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:367176 bucket->SetSize(0);
7177 return error::kNoError;
7178 }
7179
dyen0ff9e4402015-02-12 22:27:437180 // Make sure translator has been utilized in compile.
7181 shader->DoCompile();
7182
zmo576a0492014-09-13 01:12:327183 bucket->SetFromString(shader->translated_source().c_str());
[email protected]d6a53e42011-10-05 00:09:367184 return error::kNoError;
7185}
7186
[email protected]ae51d192010-04-27 00:48:037187error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
vmiuracd108592014-09-08 14:36:347188 uint32 immediate_data_size,
7189 const void* cmd_data) {
7190 const gles2::cmds::GetProgramInfoLog& c =
7191 *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427192 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:587193 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7194 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427195 Program* program = GetProgramInfoNotShader(
7196 program_id, "glGetProgramInfoLog");
7197 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:467198 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037199 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:317200 }
[email protected]df37b9932013-03-08 05:21:427201 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:037202 return error::kNoError;
7203}
7204
7205error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
vmiuracd108592014-09-08 14:36:347206 uint32 immediate_data_size,
7207 const void* cmd_data) {
7208 const gles2::cmds::GetShaderInfoLog& c =
7209 *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427210 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:587211 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7212 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427213 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
zmo576a0492014-09-13 01:12:327214 if (!shader) {
[email protected]9a14ae612011-08-08 17:51:467215 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037216 return error::kNoError;
7217 }
dyen0ff9e4402015-02-12 22:27:437218
7219 // Shader must be compiled in order to get the info log.
7220 shader->DoCompile();
7221
zmo576a0492014-09-13 01:12:327222 bucket->SetFromString(shader->log_info().c_str());
[email protected]ae51d192010-04-27 00:48:037223 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327224}
7225
[email protected]d058bca2012-11-26 10:27:267226bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
7227 return state_.GetEnabled(cap);
7228}
7229
[email protected]1958e0e2010-04-22 05:17:157230bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:217231 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107232 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157233}
7234
7235bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357236 const Framebuffer* framebuffer =
7237 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107238 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157239}
7240
7241bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367242 // IsProgram is true for programs as soon as they are created, until they are
7243 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:357244 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:107245 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157246}
7247
7248bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357249 const Renderbuffer* renderbuffer =
7250 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107251 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157252}
7253
7254bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367255 // IsShader is true for shaders as soon as they are created, until they
7256 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:357257 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:107258 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157259}
7260
7261bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:497262 const TextureRef* texture_ref = GetTexture(client_id);
7263 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:037264}
7265
7266void GLES2DecoderImpl::DoAttachShader(
7267 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427268 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587269 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:427270 if (!program) {
[email protected]ae51d192010-04-27 00:48:037271 return;
[email protected]1958e0e2010-04-22 05:17:157272 }
[email protected]df37b9932013-03-08 05:21:427273 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
7274 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037275 return;
7276 }
[email protected]df37b9932013-03-08 05:21:427277 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517278 LOCAL_SET_GL_ERROR(
7279 GL_INVALID_OPERATION,
7280 "glAttachShader",
7281 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:317282 return;
7283 }
[email protected]df37b9932013-03-08 05:21:427284 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037285}
7286
7287void GLES2DecoderImpl::DoDetachShader(
7288 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427289 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587290 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:427291 if (!program) {
[email protected]ae51d192010-04-27 00:48:037292 return;
7293 }
[email protected]df37b9932013-03-08 05:21:427294 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
7295 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037296 return;
7297 }
[email protected]df37b9932013-03-08 05:21:427298 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517299 LOCAL_SET_GL_ERROR(
7300 GL_INVALID_OPERATION,
7301 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:227302 return;
7303 }
[email protected]df37b9932013-03-08 05:21:427304 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037305}
7306
7307void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:427308 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587309 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:427310 if (!program) {
[email protected]ae51d192010-04-27 00:48:037311 return;
7312 }
[email protected]df37b9932013-03-08 05:21:427313 program->Validate();
[email protected]1958e0e2010-04-22 05:17:157314}
7315
[email protected]ac77603c72013-03-08 13:52:067316void GLES2DecoderImpl::GetVertexAttribHelper(
7317 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:247318 switch (pname) {
7319 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:067320 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:247321 if (buffer && !buffer->IsDeleted()) {
7322 GLuint client_id;
7323 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
7324 *params = client_id;
7325 }
7326 break;
7327 }
7328 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:067329 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:247330 break;
7331 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:067332 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:247333 break;
7334 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:067335 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:247336 break;
7337 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:067338 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:247339 break;
7340 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:067341 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:247342 break;
[email protected]c6aef902012-02-14 03:31:427343 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:067344 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:427345 break;
[email protected]ac77603c72013-03-08 13:52:067346 default:
7347 NOTREACHED();
7348 break;
7349 }
7350}
7351
[email protected]4c6f5462014-03-05 00:26:567352void GLES2DecoderImpl::DoGetTexParameterfv(
7353 GLenum target, GLenum pname, GLfloat* params) {
7354 InitTextureMaxAnisotropyIfNeeded(target, pname);
7355 glGetTexParameterfv(target, pname, params);
7356}
7357
7358void GLES2DecoderImpl::DoGetTexParameteriv(
7359 GLenum target, GLenum pname, GLint* params) {
7360 InitTextureMaxAnisotropyIfNeeded(target, pname);
7361 glGetTexParameteriv(target, pname, params);
7362}
7363
7364void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
7365 GLenum target, GLenum pname) {
7366 if (!workarounds().init_texture_max_anisotropy)
7367 return;
7368 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
7369 !validators_->texture_parameter.IsValid(pname)) {
7370 return;
7371 }
7372
7373 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7374 &state_, target);
7375 if (!texture_ref) {
7376 LOCAL_SET_GL_ERROR(
7377 GL_INVALID_OPERATION,
7378 "glGetTexParamter{fi}v", "unknown texture for target");
7379 return;
7380 }
7381 Texture* texture = texture_ref->texture();
7382 texture->InitTextureMaxAnisotropyIfNeeded(target);
7383}
7384
[email protected]ac77603c72013-03-08 13:52:067385void GLES2DecoderImpl::DoGetVertexAttribfv(
7386 GLuint index, GLenum pname, GLfloat* params) {
7387 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7388 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517389 LOCAL_SET_GL_ERROR(
7390 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067391 return;
7392 }
7393 switch (pname) {
7394 case GL_CURRENT_VERTEX_ATTRIB: {
7395 const Vec4& value = state_.attrib_values[index];
7396 params[0] = value.v[0];
7397 params[1] = value.v[1];
7398 params[2] = value.v[2];
7399 params[3] = value.v[3];
7400 break;
7401 }
7402 default: {
7403 GLint value = 0;
7404 GetVertexAttribHelper(attrib, pname, &value);
7405 *params = static_cast<GLfloat>(value);
7406 break;
7407 }
7408 }
7409}
7410
7411void GLES2DecoderImpl::DoGetVertexAttribiv(
7412 GLuint index, GLenum pname, GLint* params) {
7413 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7414 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517415 LOCAL_SET_GL_ERROR(
7416 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067417 return;
7418 }
7419 switch (pname) {
[email protected]af6380962012-11-29 23:24:137420 case GL_CURRENT_VERTEX_ATTRIB: {
7421 const Vec4& value = state_.attrib_values[index];
7422 params[0] = static_cast<GLint>(value.v[0]);
7423 params[1] = static_cast<GLint>(value.v[1]);
7424 params[2] = static_cast<GLint>(value.v[2]);
7425 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:247426 break;
[email protected]af6380962012-11-29 23:24:137427 }
[email protected]b1122982010-05-17 23:04:247428 default:
[email protected]ac77603c72013-03-08 13:52:067429 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:247430 break;
7431 }
7432}
7433
[email protected]af6380962012-11-29 23:24:137434bool GLES2DecoderImpl::SetVertexAttribValue(
7435 const char* function_name, GLuint index, const GLfloat* value) {
7436 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:517437 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:137438 return false;
[email protected]b1122982010-05-17 23:04:247439 }
[email protected]af6380962012-11-29 23:24:137440 Vec4& v = state_.attrib_values[index];
7441 v.v[0] = value[0];
7442 v.v[1] = value[1];
7443 v.v[2] = value[2];
7444 v.v[3] = value[3];
7445 return true;
7446}
7447
7448void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
7449 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
7450 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
7451 glVertexAttrib1f(index, v0);
7452 }
[email protected]b1122982010-05-17 23:04:247453}
7454
7455void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:137456 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7457 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7458 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:247459 }
[email protected]b1122982010-05-17 23:04:247460}
7461
7462void GLES2DecoderImpl::DoVertexAttrib3f(
7463 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:137464 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7465 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7466 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:247467 }
[email protected]b1122982010-05-17 23:04:247468}
7469
7470void GLES2DecoderImpl::DoVertexAttrib4f(
7471 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137472 GLfloat v[4] = { v0, v1, v2, v3, };
7473 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7474 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247475 }
[email protected]b1122982010-05-17 23:04:247476}
7477
7478void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137479 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7480 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7481 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247482 }
[email protected]b1122982010-05-17 23:04:247483}
7484
7485void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137486 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7487 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7488 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247489 }
[email protected]b1122982010-05-17 23:04:247490}
7491
7492void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137493 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7494 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7495 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247496 }
[email protected]b1122982010-05-17 23:04:247497}
7498
7499void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137500 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7501 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247502 }
[email protected]b1122982010-05-17 23:04:247503}
7504
zmo0c4b7cf2014-11-26 00:52:117505error::Error GLES2DecoderImpl::HandleVertexAttribIPointer(
7506 uint32 immediate_data_size,
7507 const void* cmd_data) {
7508 // TODO(zmo): Unsafe ES3 API, missing states update.
7509 if (!unsafe_es3_apis_enabled())
7510 return error::kUnknownCommand;
7511 const gles2::cmds::VertexAttribIPointer& c =
7512 *static_cast<const gles2::cmds::VertexAttribIPointer*>(cmd_data);
7513 GLuint indx = c.indx;
7514 GLint size = c.size;
7515 GLenum type = c.type;
7516 GLsizei stride = c.stride;
7517 GLsizei offset = c.offset;
7518 const void* ptr = reinterpret_cast<const void*>(offset);
7519 glVertexAttribIPointer(indx, size, type, stride, ptr);
7520 return error::kNoError;
7521}
7522
[email protected]f7a64ee2010-02-01 22:24:147523error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
vmiuracd108592014-09-08 14:36:347524 uint32 immediate_data_size,
7525 const void* cmd_data) {
7526 const gles2::cmds::VertexAttribPointer& c =
7527 *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data);
[email protected]944b62f32012-09-27 02:20:467528
[email protected]7cd76fd2013-06-02 21:11:117529 if (!state_.bound_array_buffer.get() ||
7530 state_.bound_array_buffer->IsDeleted()) {
7531 if (state_.vertex_attrib_manager.get() ==
[email protected]81f20a622014-04-18 01:54:527532 state_.default_vertex_attrib_manager.get()) {
[email protected]ab09b612013-03-11 22:11:517533 LOCAL_SET_GL_ERROR(
7534 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:467535 return error::kNoError;
7536 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:517537 LOCAL_SET_GL_ERROR(
7538 GL_INVALID_VALUE,
7539 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:467540 return error::kNoError;
7541 }
[email protected]96449d2c2009-11-25 00:01:327542 }
[email protected]8eee29c2010-04-29 03:38:297543
7544 GLuint indx = c.indx;
7545 GLint size = c.size;
7546 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327547 GLboolean normalized = static_cast<GLboolean>(c.normalized);
[email protected]8eee29c2010-04-29 03:38:297548 GLsizei stride = c.stride;
7549 GLsizei offset = c.offset;
7550 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057551 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517552 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297553 return error::kNoError;
7554 }
[email protected]9438b012010-06-15 22:55:057555 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517556 LOCAL_SET_GL_ERROR(
7557 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297558 return error::kNoError;
7559 }
7560 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517561 LOCAL_SET_GL_ERROR(
7562 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297563 return error::kNoError;
7564 }
7565 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517566 LOCAL_SET_GL_ERROR(
7567 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297568 return error::kNoError;
7569 }
7570 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517571 LOCAL_SET_GL_ERROR(
7572 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297573 return error::kNoError;
7574 }
7575 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517576 LOCAL_SET_GL_ERROR(
7577 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297578 return error::kNoError;
7579 }
7580 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317581 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]a07a23602014-08-05 11:36:127582 // component_size must be a power of two to use & as optimized modulo.
7583 DCHECK(GLES2Util::IsPOT(component_size));
7584 if (offset & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517585 LOCAL_SET_GL_ERROR(
7586 GL_INVALID_OPERATION,
7587 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317588 return error::kNoError;
7589 }
[email protected]a07a23602014-08-05 11:36:127590 if (stride & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517591 LOCAL_SET_GL_ERROR(
7592 GL_INVALID_OPERATION,
7593 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297594 return error::kNoError;
7595 }
[email protected]7cd76fd2013-06-02 21:11:117596 state_.vertex_attrib_manager
7597 ->SetAttribInfo(indx,
7598 state_.bound_array_buffer.get(),
7599 size,
7600 type,
7601 normalized,
7602 stride,
7603 stride != 0 ? stride : component_size * size,
7604 offset);
[email protected]8fbedc02010-11-18 18:43:407605 if (type != GL_FIXED) {
7606 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7607 }
[email protected]f7a64ee2010-02-01 22:24:147608 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327609}
7610
[email protected]43410e92012-04-20 17:06:287611void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7612 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247613 state_.viewport_x = x;
7614 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027615 state_.viewport_width = std::min(width, viewport_max_width_);
7616 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287617 glViewport(x, y, width, height);
7618}
7619
[email protected]c6aef902012-02-14 03:31:427620error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
vmiuracd108592014-09-08 14:36:347621 uint32 immediate_data_size,
7622 const void* cmd_data) {
7623 const gles2::cmds::VertexAttribDivisorANGLE& c =
7624 *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157625 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517626 LOCAL_SET_GL_ERROR(
7627 GL_INVALID_OPERATION,
7628 "glVertexAttribDivisorANGLE", "function not available");
[email protected]cedee332014-05-23 07:07:537629 return error::kNoError;
[email protected]c6aef902012-02-14 03:31:427630 }
7631 GLuint index = c.index;
7632 GLuint divisor = c.divisor;
7633 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517634 LOCAL_SET_GL_ERROR(
7635 GL_INVALID_VALUE,
7636 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427637 return error::kNoError;
7638 }
7639
[email protected]e259eb412012-10-13 05:47:247640 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427641 index,
7642 divisor);
7643 glVertexAttribDivisorANGLE(index, divisor);
7644 return error::kNoError;
7645}
7646
[email protected]68586372013-12-11 01:27:597647template <typename pixel_data_type>
7648static void WriteAlphaData(
7649 void *pixels, uint32 row_count, uint32 channel_count,
7650 uint32 alpha_channel_index, uint32 unpadded_row_size,
7651 uint32 padded_row_size, pixel_data_type alpha_value) {
7652 DCHECK_GT(channel_count, 0U);
7653 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7654 uint32 unpadded_row_size_in_elements =
7655 unpadded_row_size / sizeof(pixel_data_type);
7656 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7657 uint32 padded_row_size_in_elements =
7658 padded_row_size / sizeof(pixel_data_type);
7659 pixel_data_type* dst =
7660 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7661 for (uint32 yy = 0; yy < row_count; ++yy) {
7662 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7663 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7664 *d = alpha_value;
7665 }
7666 dst += padded_row_size_in_elements;
7667 }
7668}
7669
[email protected]5a36dc132013-07-23 23:17:557670void GLES2DecoderImpl::FinishReadPixels(
7671 const cmds::ReadPixels& c,
7672 GLuint buffer) {
7673 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7674 GLsizei width = c.width;
7675 GLsizei height = c.height;
7676 GLenum format = c.format;
7677 GLenum type = c.type;
7678 typedef cmds::ReadPixels::Result Result;
7679 uint32 pixels_size;
7680 Result* result = NULL;
7681 if (c.result_shm_id != 0) {
7682 result = GetSharedMemoryAs<Result*>(
7683 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7684 if (!result) {
7685 if (buffer != 0) {
7686 glDeleteBuffersARB(1, &buffer);
7687 }
7688 return;
7689 }
7690 }
7691 GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427692 width, height, 1, format, type, state_.pack_alignment, &pixels_size,
[email protected]5a36dc132013-07-23 23:17:557693 NULL, NULL);
7694 void* pixels = GetSharedMemoryAs<void*>(
7695 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7696 if (!pixels) {
7697 if (buffer != 0) {
7698 glDeleteBuffersARB(1, &buffer);
7699 }
7700 return;
7701 }
7702
7703 if (buffer != 0) {
7704 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337705 void* data;
7706 if (features().map_buffer_range) {
7707 data = glMapBufferRange(
7708 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7709 } else {
7710 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7711 }
miub70d78592014-11-15 03:53:477712 if (!data) {
7713 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glMapBuffer",
7714 "Unable to map memory for readback.");
7715 return;
7716 }
[email protected]5a36dc132013-07-23 23:17:557717 memcpy(pixels, data, pixels_size);
7718 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7719 // have to restore the state.
7720 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7721 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7722 glDeleteBuffersARB(1, &buffer);
7723 }
7724
7725 if (result != NULL) {
7726 *result = true;
7727 }
7728
7729 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7730 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7731 if ((channels_exist & 0x0008) == 0 &&
7732 workarounds().clear_alpha_in_readpixels) {
7733 // Set the alpha to 255 because some drivers are buggy in this regard.
7734 uint32 temp_size;
7735
7736 uint32 unpadded_row_size;
7737 uint32 padded_row_size;
7738 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427739 width, 2, 1, format, type, state_.pack_alignment, &temp_size,
[email protected]5a36dc132013-07-23 23:17:557740 &unpadded_row_size, &padded_row_size)) {
7741 return;
7742 }
[email protected]68586372013-12-11 01:27:597743
7744 uint32 channel_count = 0;
7745 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557746 switch (format) {
7747 case GL_RGBA:
7748 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597749 channel_count = 4;
7750 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557751 break;
[email protected]68586372013-12-11 01:27:597752 case GL_ALPHA:
7753 channel_count = 1;
7754 alpha_channel = 0;
7755 break;
7756 }
7757
7758 if (channel_count > 0) {
7759 switch (type) {
7760 case GL_UNSIGNED_BYTE:
7761 WriteAlphaData<uint8>(
7762 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7763 padded_row_size, 0xFF);
7764 break;
7765 case GL_FLOAT:
7766 WriteAlphaData<float>(
7767 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7768 padded_row_size, 1.0f);
7769 break;
7770 case GL_HALF_FLOAT:
7771 WriteAlphaData<uint16>(
7772 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7773 padded_row_size, 0x3C00);
7774 break;
[email protected]5a36dc132013-07-23 23:17:557775 }
[email protected]5a36dc132013-07-23 23:17:557776 }
7777 }
7778}
7779
vmiuracd108592014-09-08 14:36:347780error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
7781 const void* cmd_data) {
7782 const gles2::cmds::ReadPixels& c =
7783 *static_cast<const gles2::cmds::ReadPixels*>(cmd_data);
[email protected]c959a09a2014-03-27 11:44:217784 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
[email protected]c76fe672013-12-13 23:30:227785 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7786 if (fbo_error != error::kNoError)
7787 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317788 GLint x = c.x;
7789 GLint y = c.y;
7790 GLsizei width = c.width;
7791 GLsizei height = c.height;
7792 GLenum format = c.format;
7793 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327794 GLboolean async = static_cast<GLboolean>(c.async);
[email protected]57f223832010-03-19 01:57:567795 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517796 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567797 return error::kNoError;
7798 }
[email protected]ed9f9cd2013-02-27 21:12:357799 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187800 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347801 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427802 width, height, 1, format, type, state_.pack_alignment, &pixels_size,
[email protected]e259eb412012-10-13 05:47:247803 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187804 return error::kOutOfBounds;
7805 }
[email protected]612d2f82009-12-08 20:49:317806 void* pixels = GetSharedMemoryAs<void*>(
7807 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107808 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147809 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467810 }
[email protected]de43f082013-04-02 01:16:107811 Result* result = NULL;
7812 if (c.result_shm_id != 0) {
7813 result = GetSharedMemoryAs<Result*>(
7814 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7815 if (!result) {
7816 return error::kOutOfBounds;
7817 }
7818 }
[email protected]a51788e2010-02-24 21:54:257819
[email protected]9438b012010-06-15 22:55:057820 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517821 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297822 return error::kNoError;
7823 }
[email protected]68586372013-12-11 01:27:597824 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517825 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127826 return error::kNoError;
7827 }
[email protected]68586372013-12-11 01:27:597828 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7829 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7830 // format and type are acceptable enums but not guaranteed to be supported
7831 // for this framebuffer. Have to ask gl if they are valid.
7832 GLint preferred_format = 0;
7833 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7834 GLint preferred_type = 0;
7835 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7836 if (format != static_cast<GLenum>(preferred_format) ||
7837 type != static_cast<GLenum>(preferred_type)) {
7838 LOCAL_SET_GL_ERROR(
7839 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7840 "with the current read framebuffer");
7841 return error::kNoError;
7842 }
7843 }
[email protected]57f223832010-03-19 01:57:567844 if (width == 0 || height == 0) {
7845 return error::kNoError;
7846 }
7847
[email protected]57f223832010-03-19 01:57:567848 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307849 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567850
[email protected]3aad1a32012-09-07 20:54:477851 int32 max_x;
7852 int32 max_y;
7853 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517854 LOCAL_SET_GL_ERROR(
7855 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147856 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317857 }
[email protected]57f223832010-03-19 01:57:567858
[email protected]2ea5950d2014-07-09 18:20:347859 if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) {
7860 return error::kNoError;
7861 }
7862
[email protected]0d6bfdc2011-11-02 01:32:207863 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7864 return error::kNoError;
7865 }
7866
[email protected]caa13ed2014-02-17 11:29:207867 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:107868
7869 ScopedResolvedFrameBufferBinder binder(this, false, true);
7870
[email protected]d37231fa2010-04-09 21:16:027871 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567872 // The user requested an out of range area. Get the results 1 line
7873 // at a time.
7874 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347875 uint32 unpadded_row_size;
7876 uint32 padded_row_size;
7877 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427878 width, 2, 1, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347879 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517880 LOCAL_SET_GL_ERROR(
7881 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567882 return error::kNoError;
7883 }
7884
7885 GLint dest_x_offset = std::max(-x, 0);
7886 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347887 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427888 dest_x_offset, 1, 1, format, type, state_.pack_alignment,
7889 &dest_row_offset, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517890 LOCAL_SET_GL_ERROR(
7891 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567892 return error::kNoError;
7893 }
7894
7895 // Copy each row into the larger dest rect.
7896 int8* dst = static_cast<int8*>(pixels);
7897 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027898 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567899 GLint read_width = read_end_x - read_x;
7900 for (GLint yy = 0; yy < height; ++yy) {
7901 GLint ry = y + yy;
7902
7903 // Clear the row.
7904 memset(dst, 0, unpadded_row_size);
7905
7906 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027907 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567908 glReadPixels(
7909 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7910 }
7911 dst += padded_row_size;
7912 }
7913 } else {
[email protected]5a36dc132013-07-23 23:17:557914 if (async && features().use_async_readpixels) {
miu50cef602014-11-11 01:35:417915 GLuint buffer = 0;
[email protected]5a36dc132013-07-23 23:17:557916 glGenBuffersARB(1, &buffer);
7917 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
miub70d78592014-11-15 03:53:477918 // For ANGLE client version 2, GL_STREAM_READ is not available.
zmo68fcdc62014-12-05 21:51:497919 const GLenum usage_hint = feature_info_->gl_version_info().is_angle ?
7920 GL_STATIC_DRAW : GL_STREAM_READ;
miub70d78592014-11-15 03:53:477921 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, usage_hint);
[email protected]5a36dc132013-07-23 23:17:557922 GLenum error = glGetError();
7923 if (error == GL_NO_ERROR) {
7924 glReadPixels(x, y, width, height, format, type, 0);
7925 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7926 new FenceCallback()));
7927 WaitForReadPixels(base::Bind(
7928 &GLES2DecoderImpl::FinishReadPixels,
7929 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7930 <GLES2DecoderImpl>(this),
7931 c, buffer));
7932 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7933 return error::kNoError;
[email protected]77bfe7442014-03-01 02:42:597934 } else {
7935 // On error, unbind pack buffer and fall through to sync readpixels
7936 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
miu50cef602014-11-11 01:35:417937 glDeleteBuffersARB(1, &buffer);
[email protected]5a36dc132013-07-23 23:17:557938 }
7939 }
[email protected]57f223832010-03-19 01:57:567940 glReadPixels(x, y, width, height, format, type, pixels);
7941 }
[email protected]ab09b612013-03-11 22:11:517942 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257943 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107944 if (result != NULL) {
7945 *result = true;
7946 }
[email protected]5a36dc132013-07-23 23:17:557947 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257948 }
[email protected]4848b9f82011-03-10 18:37:567949
[email protected]f7a64ee2010-02-01 22:24:147950 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327951}
7952
vmiuracd108592014-09-08 14:36:347953error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size,
7954 const void* cmd_data) {
7955 const gles2::cmds::PixelStorei& c =
7956 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:197957 GLenum pname = c.pname;
7958 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057959 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517960 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127961 return error::kNoError;
7962 }
[email protected]222471d2011-11-30 18:06:397963 switch (pname) {
7964 case GL_PACK_ALIGNMENT:
7965 case GL_UNPACK_ALIGNMENT:
7966 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517967 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:207968 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397969 return error::kNoError;
7970 }
[email protected]164d6d52012-05-05 00:55:037971 break;
[email protected]0a1e9ad2012-05-04 21:13:037972 case GL_UNPACK_FLIP_Y_CHROMIUM:
7973 unpack_flip_y_ = (param != 0);
7974 return error::kNoError;
7975 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7976 unpack_premultiply_alpha_ = (param != 0);
7977 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177978 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7979 unpack_unpremultiply_alpha_ = (param != 0);
7980 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397981 default:
7982 break;
[email protected]b9849abf2009-11-25 19:13:197983 }
7984 glPixelStorei(pname, param);
7985 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437986 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247987 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437988 break;
7989 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427990 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437991 break;
7992 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247993 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437994 break;
7995 default:
7996 // Validation should have prevented us from getting here.
7997 NOTREACHED();
7998 break;
[email protected]b9849abf2009-11-25 19:13:197999 }
[email protected]f7a64ee2010-02-01 22:24:148000 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198001}
8002
[email protected]1c75a3702011-11-11 14:15:288003error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
vmiuracd108592014-09-08 14:36:348004 uint32 immediate_data_size,
8005 const void* cmd_data) {
8006 const gles2::cmds::PostSubBufferCHROMIUM& c =
8007 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data);
[email protected]43ed3a72012-05-30 22:55:388008 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]a36ed4832014-04-24 16:40:278009 {
8010 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
8011 }
[email protected]b381ee32014-03-22 02:43:438012 if (!supports_post_sub_buffer_) {
[email protected]ab09b612013-03-11 22:11:518013 LOCAL_SET_GL_ERROR(
8014 GL_INVALID_OPERATION,
8015 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:288016 return error::kNoError;
8017 }
[email protected]8f9b8dd2013-09-12 18:05:138018 bool is_tracing;
8019 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
8020 &is_tracing);
8021 if (is_tracing) {
8022 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
8023 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
8024 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
8025 is_offscreen ? offscreen_size_ : surface_->GetSize());
8026 }
[email protected]7794d512012-04-17 20:36:498027 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:288028 return error::kNoError;
[email protected]7794d512012-04-17 20:36:498029 } else {
8030 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:288031 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:498032 }
[email protected]1c75a3702011-11-11 14:15:288033}
8034
[email protected]957f0642014-04-09 16:50:018035error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
8036 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348037 const void* cmd_data) {
8038 const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
8039 *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data);
[email protected]d286ebbc2014-07-03 17:19:108040 TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
8041 if (!ref) {
8042 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
8043 "glScheduleOverlayPlaneCHROMIUM",
8044 "unknown texture");
8045 return error::kNoError;
8046 }
8047 gfx::GLImage* image =
8048 ref->texture()->GetLevelImage(ref->texture()->target(), 0);
8049 if (!image) {
8050 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
8051 "glScheduleOverlayPlaneCHROMIUM",
8052 "unsupported texture format");
8053 return error::kNoError;
8054 }
8055 gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
8056 if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
8057 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
8058 "glScheduleOverlayPlaneCHROMIUM",
8059 "invalid transform enum");
8060 return error::kNoError;
8061 }
8062 if (!surface_->ScheduleOverlayPlane(
8063 c.plane_z_order,
8064 transform,
8065 image,
8066 gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
8067 gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) {
8068 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
8069 "glScheduleOverlayPlaneCHROMIUM",
8070 "failed to schedule overlay");
8071 }
[email protected]957f0642014-04-09 16:50:018072 return error::kNoError;
8073}
8074
[email protected]558847a2010-03-24 07:02:548075error::Error GLES2DecoderImpl::GetAttribLocationHelper(
8076 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8077 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578078 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518079 LOCAL_SET_GL_ERROR(
8080 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578081 return error::kNoError;
8082 }
[email protected]df37b9932013-03-08 05:21:428083 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:588084 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:428085 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148086 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198087 }
[email protected]df37b9932013-03-08 05:21:428088 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518089 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438090 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258091 return error::kNoError;
8092 }
[email protected]b9849abf2009-11-25 19:13:198093 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548094 location_shm_id, location_shm_offset, sizeof(GLint));
8095 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148096 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198097 }
[email protected]558847a2010-03-24 07:02:548098 // Require the client to init this incase the context is lost and we are no
8099 // longer executing commands.
8100 if (*location != -1) {
8101 return error::kGenericError;
8102 }
[email protected]df37b9932013-03-08 05:21:428103 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148104 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198105}
8106
[email protected]558847a2010-03-24 07:02:548107error::Error GLES2DecoderImpl::HandleGetAttribLocation(
vmiuracd108592014-09-08 14:36:348108 uint32 immediate_data_size,
8109 const void* cmd_data) {
8110 const gles2::cmds::GetAttribLocation& c =
8111 *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548112 Bucket* bucket = GetBucket(c.name_bucket_id);
8113 if (!bucket) {
8114 return error::kInvalidArguments;
8115 }
8116 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188117 if (!bucket->GetAsString(&name_str)) {
8118 return error::kInvalidArguments;
8119 }
[email protected]558847a2010-03-24 07:02:548120 return GetAttribLocationHelper(
8121 c.program, c.location_shm_id, c.location_shm_offset, name_str);
8122}
8123
8124error::Error GLES2DecoderImpl::GetUniformLocationHelper(
8125 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8126 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578127 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518128 LOCAL_SET_GL_ERROR(
8129 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578130 return error::kNoError;
8131 }
[email protected]df37b9932013-03-08 05:21:428132 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:208133 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:428134 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148135 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198136 }
[email protected]df37b9932013-03-08 05:21:428137 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518138 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438139 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258140 return error::kNoError;
8141 }
[email protected]b9849abf2009-11-25 19:13:198142 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548143 location_shm_id, location_shm_offset, sizeof(GLint));
8144 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148145 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198146 }
[email protected]558847a2010-03-24 07:02:548147 // Require the client to init this incase the context is lost an we are no
8148 // longer executing commands.
8149 if (*location != -1) {
8150 return error::kGenericError;
8151 }
[email protected]df37b9932013-03-08 05:21:428152 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148153 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198154}
8155
[email protected]f7a64ee2010-02-01 22:24:148156error::Error GLES2DecoderImpl::HandleGetUniformLocation(
vmiuracd108592014-09-08 14:36:348157 uint32 immediate_data_size,
8158 const void* cmd_data) {
8159 const gles2::cmds::GetUniformLocation& c =
8160 *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548161 Bucket* bucket = GetBucket(c.name_bucket_id);
8162 if (!bucket) {
8163 return error::kInvalidArguments;
8164 }
8165 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188166 if (!bucket->GetAsString(&name_str)) {
8167 return error::kInvalidArguments;
8168 }
[email protected]558847a2010-03-24 07:02:548169 return GetUniformLocationHelper(
8170 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:198171}
8172
zmo5393fb52015-01-27 01:50:488173error::Error GLES2DecoderImpl::GetFragDataLocationHelper(
8174 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8175 const std::string& name_str) {
8176 GLint* location = GetSharedMemoryAs<GLint*>(
8177 location_shm_id, location_shm_offset, sizeof(GLint));
8178 if (!location) {
8179 return error::kOutOfBounds;
8180 }
8181 // Require the client to init this incase the context is lost and we are no
8182 // longer executing commands.
8183 if (*location != -1) {
8184 return error::kGenericError;
8185 }
8186 Program* program = GetProgramInfoNotShader(
8187 client_id, "glGetFragDataLocation");
8188 if (!program) {
8189 return error::kNoError;
8190 }
8191 *location = glGetFragDataLocation(program->service_id(), name_str.c_str());
8192 return error::kNoError;
8193}
8194
8195error::Error GLES2DecoderImpl::HandleGetFragDataLocation(
8196 uint32 immediate_data_size,
8197 const void* cmd_data) {
8198 if (!unsafe_es3_apis_enabled())
8199 return error::kUnknownCommand;
8200 const gles2::cmds::GetFragDataLocation& c =
8201 *static_cast<const gles2::cmds::GetFragDataLocation*>(cmd_data);
8202 Bucket* bucket = GetBucket(c.name_bucket_id);
8203 if (!bucket) {
8204 return error::kInvalidArguments;
8205 }
8206 std::string name_str;
8207 if (!bucket->GetAsString(&name_str)) {
8208 return error::kInvalidArguments;
8209 }
8210 return GetFragDataLocationHelper(
8211 c.program, c.location_shm_id, c.location_shm_offset, name_str);
8212}
8213
zmo4a16ff992015-02-05 22:18:418214error::Error GLES2DecoderImpl::HandleGetUniformBlockIndex(
8215 uint32 immediate_data_size, const void* cmd_data) {
8216 if (!unsafe_es3_apis_enabled())
8217 return error::kUnknownCommand;
8218 const gles2::cmds::GetUniformBlockIndex& c =
8219 *static_cast<const gles2::cmds::GetUniformBlockIndex*>(cmd_data);
8220 Bucket* bucket = GetBucket(c.name_bucket_id);
8221 if (!bucket) {
8222 return error::kInvalidArguments;
8223 }
8224 std::string name_str;
8225 if (!bucket->GetAsString(&name_str)) {
8226 return error::kInvalidArguments;
8227 }
8228 GLuint* index = GetSharedMemoryAs<GLuint*>(
8229 c.index_shm_id, c.index_shm_offset, sizeof(GLuint));
8230 if (!index) {
8231 return error::kOutOfBounds;
8232 }
8233 // Require the client to init this in case the context is lost and we are no
8234 // longer executing commands.
8235 if (*index != GL_INVALID_INDEX) {
8236 return error::kGenericError;
8237 }
8238 Program* program = GetProgramInfoNotShader(
8239 c.program, "glGetUniformBlockIndex");
8240 if (!program) {
8241 return error::kNoError;
8242 }
8243 *index = glGetUniformBlockIndex(program->service_id(), name_str.c_str());
8244 return error::kNoError;
8245}
8246
vmiuracd108592014-09-08 14:36:348247error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
8248 const void* cmd_data) {
8249 const gles2::cmds::GetString& c =
8250 *static_cast<const gles2::cmds::GetString*>(cmd_data);
[email protected]ddd968b82010-03-02 00:44:298251 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:058252 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:518253 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:298254 return error::kNoError;
8255 }
[email protected]959e9072013-09-20 16:58:388256 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:048257 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:158258 switch (name) {
8259 case GL_VERSION:
8260 str = "OpenGL ES 2.0 Chromium";
8261 break;
8262 case GL_SHADING_LANGUAGE_VERSION:
8263 str = "OpenGL ES GLSL ES 1.0 Chromium";
8264 break;
[email protected]32939602012-05-09 06:25:168265 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:168266 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:388267 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
8268 // They are used by WEBGL_debug_renderer_info.
8269 if (!force_webgl_glsl_validation_)
8270 str = "Chromium";
[email protected]32939602012-05-09 06:25:168271 break;
[email protected]1958e0e2010-04-22 05:17:158272 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:048273 {
[email protected]70dc60932013-06-04 03:33:498274 // For WebGL contexts, strip out the OES derivatives and
8275 // EXT frag depth extensions if they have not been enabled.
8276 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:048277 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:498278 if (!derivatives_explicitly_enabled_) {
8279 size_t offset = extensions.find(kOESDerivativeExtension);
8280 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098281 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:498282 std::string());
8283 }
8284 }
8285 if (!frag_depth_explicitly_enabled_) {
8286 size_t offset = extensions.find(kEXTFragDepthExtension);
8287 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098288 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:498289 std::string());
8290 }
[email protected]f0d74742011-10-03 16:31:048291 }
[email protected]aff39ac82013-06-08 04:53:138292 if (!draw_buffers_explicitly_enabled_) {
8293 size_t offset = extensions.find(kEXTDrawBuffersExtension);
8294 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098295 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:138296 std::string());
8297 }
8298 }
[email protected]93c2fd82014-04-16 02:46:068299 if (!shader_texture_lod_explicitly_enabled_) {
8300 size_t offset = extensions.find(kEXTShaderTextureLodExtension);
8301 if (std::string::npos != offset) {
8302 extensions.replace(offset,
8303 arraysize(kEXTShaderTextureLodExtension),
8304 std::string());
8305 }
8306 }
[email protected]f0d74742011-10-03 16:31:048307 } else {
[email protected]6f5fac9d12012-06-26 21:02:458308 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:048309 }
[email protected]b381ee32014-03-22 02:43:438310 if (supports_post_sub_buffer_)
8311 extensions += " GL_CHROMIUM_post_sub_buffer";
[email protected]6f5fac9d12012-06-26 21:02:458312 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:048313 }
[email protected]1958e0e2010-04-22 05:17:158314 break;
8315 default:
[email protected]1958e0e2010-04-22 05:17:158316 break;
8317 }
[email protected]ddd968b82010-03-02 00:44:298318 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:158319 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:298320 return error::kNoError;
8321}
8322
vmiuracd108592014-09-08 14:36:348323error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size,
8324 const void* cmd_data) {
8325 const gles2::cmds::BufferData& c =
8326 *static_cast<const gles2::cmds::BufferData*>(cmd_data);
[email protected]0c86dbf2010-03-05 08:14:118327 GLenum target = static_cast<GLenum>(c.target);
8328 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
8329 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8330 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8331 GLenum usage = static_cast<GLenum>(c.usage);
8332 const void* data = NULL;
8333 if (data_shm_id != 0 || data_shm_offset != 0) {
8334 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
8335 if (!data) {
8336 return error::kOutOfBounds;
8337 }
8338 }
[email protected]0fbba3732013-07-17 15:40:138339 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:148340 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198341}
8342
[email protected]0c86dbf2010-03-05 08:14:118343void GLES2DecoderImpl::DoBufferSubData(
8344 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:138345 // Just delegate it. Some validation is actually done before this.
8346 buffer_manager()->ValidateAndDoBufferSubData(
8347 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:198348}
8349
[email protected]0d6bfdc2011-11-02 01:32:208350bool GLES2DecoderImpl::ClearLevel(
8351 unsigned service_id,
8352 unsigned bind_target,
8353 unsigned target,
8354 int level,
[email protected]d8e6c9242014-02-20 16:56:258355 unsigned internal_format,
[email protected]0d6bfdc2011-11-02 01:32:208356 unsigned format,
8357 unsigned type,
8358 int width,
[email protected]4502e6492011-12-14 19:39:158359 int height,
8360 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:008361 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:008362 if (feature_info_->feature_flags().angle_depth_texture &&
8363 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:008364 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
8365 // on depth formats.
8366 GLuint fb = 0;
8367 glGenFramebuffersEXT(1, &fb);
8368 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
8369
8370 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
8371 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
8372 GL_DEPTH_ATTACHMENT;
8373
8374 glFramebufferTexture2DEXT(
8375 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
8376 // ANGLE promises a depth only attachment ok.
8377 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
8378 GL_FRAMEBUFFER_COMPLETE) {
8379 return false;
8380 }
8381 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:478382 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
8383 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]81375742012-06-08 00:04:008384 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:458385 state_.SetDeviceDepthMask(GL_TRUE);
8386 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]81375742012-06-08 00:04:008387 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
8388
8389 RestoreClearState();
8390
8391 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:358392 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:008393 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
8394 GLuint fb_service_id =
8395 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
8396 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
8397 return true;
8398 }
8399
[email protected]45d15a62012-04-18 14:33:178400 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
8401
8402 uint32 size;
8403 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:348404 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428405 width, height, 1, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:178406 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:208407 return false;
8408 }
[email protected]45d15a62012-04-18 14:33:178409
[email protected]a5d3dad2012-05-26 04:34:448410 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
8411
[email protected]45d15a62012-04-18 14:33:178412 int tile_height;
8413
8414 if (size > kMaxZeroSize) {
8415 if (kMaxZeroSize < padded_row_size) {
8416 // That'd be an awfully large texture.
8417 return false;
8418 }
8419 // We should never have a large total size with a zero row size.
8420 DCHECK_GT(padded_row_size, 0U);
8421 tile_height = kMaxZeroSize / padded_row_size;
8422 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428423 width, tile_height, 1, format, type, state_.unpack_alignment, &size,
[email protected]e259eb412012-10-13 05:47:248424 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:178425 return false;
8426 }
[email protected]4502e6492011-12-14 19:39:158427 } else {
[email protected]45d15a62012-04-18 14:33:178428 tile_height = height;
8429 }
8430
8431 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:558432 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:178433 memset(zero.get(), 0, size);
8434 glBindTexture(bind_target, service_id);
8435
8436 GLint y = 0;
8437 while (y < height) {
8438 GLint h = y + tile_height > height ? height - y : tile_height;
8439 if (is_texture_immutable || h != height) {
8440 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
8441 } else {
[email protected]8f1d2aa2013-05-10 23:45:388442 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258443 target, level, internal_format, width, h, 0, format, type,
8444 zero.get());
[email protected]45d15a62012-04-18 14:33:178445 }
8446 y += tile_height;
[email protected]4502e6492011-12-14 19:39:158447 }
[email protected]c986af502013-08-14 01:04:448448 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
8449 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:078450 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:208451 return true;
8452}
8453
[email protected]ad84a3a2012-06-08 21:42:438454namespace {
8455
8456const int kS3TCBlockWidth = 4;
8457const int kS3TCBlockHeight = 4;
8458const int kS3TCDXT1BlockSize = 8;
8459const int kS3TCDXT3AndDXT5BlockSize = 16;
8460
8461bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:518462 return (size == 1) ||
8463 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:438464}
8465
[email protected]8aec81ec2014-04-29 01:04:518466bool IsValidPVRTCSize(GLint level, GLsizei size) {
[email protected]a07a23602014-08-05 11:36:128467 return GLES2Util::IsPOT(size);
[email protected]8aec81ec2014-04-29 01:04:518468}
8469
[email protected]ad84a3a2012-06-08 21:42:438470} // anonymous namespace.
8471
8472bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
8473 const char* function_name,
8474 GLsizei width, GLsizei height, GLenum format, size_t size) {
8475 unsigned int bytes_required = 0;
8476
8477 switch (format) {
[email protected]8aec81ec2014-04-29 01:04:518478 case GL_ATC_RGB_AMD:
[email protected]ad84a3a2012-06-08 21:42:438479 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
[email protected]8aec81ec2014-04-29 01:04:518480 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8481 case GL_ETC1_RGB8_OES: {
[email protected]ad84a3a2012-06-08 21:42:438482 int num_blocks_across =
8483 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8484 int num_blocks_down =
8485 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8486 int num_blocks = num_blocks_across * num_blocks_down;
8487 bytes_required = num_blocks * kS3TCDXT1BlockSize;
8488 break;
8489 }
[email protected]8aec81ec2014-04-29 01:04:518490 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8491 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
[email protected]ad84a3a2012-06-08 21:42:438492 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8493 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8494 int num_blocks_across =
8495 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8496 int num_blocks_down =
8497 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8498 int num_blocks = num_blocks_across * num_blocks_down;
8499 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
8500 break;
8501 }
[email protected]8aec81ec2014-04-29 01:04:518502 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8503 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: {
8504 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8;
8505 break;
8506 }
8507 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8508 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8509 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8;
[email protected]2d3765b2012-10-03 00:31:078510 break;
8511 }
[email protected]ad84a3a2012-06-08 21:42:438512 default:
[email protected]ab09b612013-03-11 22:11:518513 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:438514 return false;
8515 }
8516
8517 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:518518 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438519 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
8520 return false;
8521 }
8522
8523 return true;
8524}
8525
8526bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
8527 const char* function_name,
8528 GLint level, GLsizei width, GLsizei height, GLenum format) {
8529 switch (format) {
8530 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8531 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8532 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8533 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8534 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:518535 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438536 GL_INVALID_OPERATION, function_name,
8537 "width or height invalid for level");
8538 return false;
8539 }
8540 return true;
8541 }
[email protected]8aec81ec2014-04-29 01:04:518542 case GL_ATC_RGB_AMD:
8543 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8544 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
8545 case GL_ETC1_RGB8_OES: {
[email protected]2d3765b2012-10-03 00:31:078546 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:518547 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078548 GL_INVALID_OPERATION, function_name,
8549 "width or height invalid for level");
8550 return false;
8551 }
8552 return true;
[email protected]8aec81ec2014-04-29 01:04:518553 }
8554 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8555 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8556 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8557 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8558 if (!IsValidPVRTCSize(level, width) ||
8559 !IsValidPVRTCSize(level, height)) {
8560 LOCAL_SET_GL_ERROR(
8561 GL_INVALID_OPERATION, function_name,
8562 "width or height invalid for level");
8563 return false;
8564 }
8565 return true;
8566 }
[email protected]ad84a3a2012-06-08 21:42:438567 default:
8568 return false;
8569 }
8570}
8571
8572bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
8573 const char* function_name,
8574 GLenum target, GLint level, GLint xoffset, GLint yoffset,
8575 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:358576 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:438577 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:518578 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438579 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
8580 return false;
8581 }
8582
8583 switch (format) {
8584 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8585 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8586 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8587 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8588 const int kBlockWidth = 4;
8589 const int kBlockHeight = 4;
8590 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:518591 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438592 GL_INVALID_OPERATION, function_name,
8593 "xoffset or yoffset not multiple of 4");
8594 return false;
8595 }
8596 GLsizei tex_width = 0;
8597 GLsizei tex_height = 0;
8598 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8599 width - xoffset > tex_width ||
8600 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:518601 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438602 GL_INVALID_OPERATION, function_name, "dimensions out of range");
8603 return false;
8604 }
8605 return ValidateCompressedTexDimensions(
8606 function_name, level, width, height, format);
8607 }
[email protected]8aec81ec2014-04-29 01:04:518608 case GL_ATC_RGB_AMD:
8609 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8610 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
8611 LOCAL_SET_GL_ERROR(
8612 GL_INVALID_OPERATION, function_name,
8613 "not supported for ATC textures");
8614 return false;
8615 }
[email protected]2d3765b2012-10-03 00:31:078616 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:518617 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078618 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:208619 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:078620 return false;
8621 }
[email protected]8aec81ec2014-04-29 01:04:518622 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8623 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8624 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8625 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8626 if ((xoffset != 0) || (yoffset != 0)) {
8627 LOCAL_SET_GL_ERROR(
8628 GL_INVALID_OPERATION, function_name,
8629 "xoffset and yoffset must be zero");
8630 return false;
8631 }
8632 GLsizei tex_width = 0;
8633 GLsizei tex_height = 0;
8634 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8635 width != tex_width ||
8636 height != tex_height) {
8637 LOCAL_SET_GL_ERROR(
8638 GL_INVALID_OPERATION, function_name,
8639 "dimensions must match existing texture level dimensions");
8640 return false;
8641 }
8642 return ValidateCompressedTexDimensions(
8643 function_name, level, width, height, format);
8644 }
[email protected]ad84a3a2012-06-08 21:42:438645 default:
8646 return false;
8647 }
8648}
8649
[email protected]a93bb842010-02-16 23:03:478650error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
8651 GLenum target,
8652 GLint level,
8653 GLenum internal_format,
8654 GLsizei width,
8655 GLsizei height,
8656 GLint border,
8657 GLsizei image_size,
8658 const void* data) {
[email protected]a93bb842010-02-16 23:03:478659 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:058660 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518661 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8662 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:298663 return error::kNoError;
8664 }
[email protected]9438b012010-06-15 22:55:058665 if (!validators_->compressed_texture_format.IsValid(
8666 internal_format)) {
[email protected]ab09b612013-03-11 22:11:518667 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538668 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:478669 return error::kNoError;
8670 }
[email protected]80eb6b52012-01-19 00:14:418671 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:478672 border != 0) {
[email protected]ab09b612013-03-11 22:11:518673 LOCAL_SET_GL_ERROR(
8674 GL_INVALID_VALUE,
8675 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:478676 return error::kNoError;
8677 }
[email protected]c986af502013-08-14 01:04:448678 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8679 &state_, target);
[email protected]370eaf12013-05-18 09:19:498680 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518681 LOCAL_SET_GL_ERROR(
8682 GL_INVALID_VALUE,
8683 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:478684 return error::kNoError;
8685 }
[email protected]370eaf12013-05-18 09:19:498686 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078687 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518688 LOCAL_SET_GL_ERROR(
8689 GL_INVALID_OPERATION,
8690 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:438691 return error::kNoError;
8692 }
8693
8694 if (!ValidateCompressedTexDimensions(
8695 "glCompressedTexImage2D", level, width, height, internal_format) ||
8696 !ValidateCompressedTexFuncData(
8697 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:178698 return error::kNoError;
8699 }
[email protected]968351b2011-12-20 08:26:518700
[email protected]7989c9e2013-01-23 06:39:268701 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:518702 LOCAL_SET_GL_ERROR(
8703 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268704 return error::kNoError;
8705 }
8706
[email protected]02965c22013-03-09 02:40:078707 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448708 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:518709 }
8710
[email protected]40d90a22013-04-09 03:39:558711 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:478712 if (!data) {
8713 zero.reset(new int8[image_size]);
8714 memset(zero.get(), 0, image_size);
8715 data = zero.get();
8716 }
[email protected]ab09b612013-03-11 22:11:518717 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:478718 glCompressedTexImage2D(
8719 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:518720 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438721 if (error == GL_NO_ERROR) {
8722 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498723 texture_ref, target, level, internal_format,
8724 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:438725 }
vmiura8266ca72014-09-09 21:37:008726
8727 // This may be a slow command. Exit command processing to allow for
8728 // context preemption and GPU watchdog checks.
8729 ExitCommandProcessingEarly();
[email protected]a93bb842010-02-16 23:03:478730 return error::kNoError;
8731}
8732
[email protected]f7a64ee2010-02-01 22:24:148733error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
vmiuracd108592014-09-08 14:36:348734 uint32 immediate_data_size,
8735 const void* cmd_data) {
8736 const gles2::cmds::CompressedTexImage2D& c =
8737 *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:198738 GLenum target = static_cast<GLenum>(c.target);
8739 GLint level = static_cast<GLint>(c.level);
8740 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8741 GLsizei width = static_cast<GLsizei>(c.width);
8742 GLsizei height = static_cast<GLsizei>(c.height);
8743 GLint border = static_cast<GLint>(c.border);
8744 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
8745 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8746 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8747 const void* data = NULL;
8748 if (data_shm_id != 0 || data_shm_offset != 0) {
8749 data = GetSharedMemoryAs<const void*>(
8750 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:468751 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:148752 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198753 }
8754 }
[email protected]a93bb842010-02-16 23:03:478755 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:198756 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:198757}
8758
[email protected]b6140d02010-05-17 14:47:168759error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
vmiuracd108592014-09-08 14:36:348760 uint32 immediate_data_size,
8761 const void* cmd_data) {
8762 const gles2::cmds::CompressedTexImage2DBucket& c =
8763 *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168764 GLenum target = static_cast<GLenum>(c.target);
8765 GLint level = static_cast<GLint>(c.level);
8766 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8767 GLsizei width = static_cast<GLsizei>(c.width);
8768 GLsizei height = static_cast<GLsizei>(c.height);
8769 GLint border = static_cast<GLint>(c.border);
8770 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288771 if (!bucket) {
8772 return error::kInvalidArguments;
8773 }
8774 uint32 data_size = bucket->size();
8775 GLsizei imageSize = data_size;
8776 const void* data = bucket->GetData(0, data_size);
8777 if (!data) {
8778 return error::kInvalidArguments;
8779 }
[email protected]b6140d02010-05-17 14:47:168780 return DoCompressedTexImage2D(
8781 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:288782 imageSize, data);
[email protected]b6140d02010-05-17 14:47:168783}
8784
8785error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8786 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348787 const void* cmd_data) {
8788 const gles2::cmds::CompressedTexSubImage2DBucket& c =
8789 *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168790 GLenum target = static_cast<GLenum>(c.target);
8791 GLint level = static_cast<GLint>(c.level);
8792 GLint xoffset = static_cast<GLint>(c.xoffset);
8793 GLint yoffset = static_cast<GLint>(c.yoffset);
8794 GLsizei width = static_cast<GLsizei>(c.width);
8795 GLsizei height = static_cast<GLsizei>(c.height);
8796 GLenum format = static_cast<GLenum>(c.format);
8797 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288798 if (!bucket) {
8799 return error::kInvalidArguments;
8800 }
[email protected]b6140d02010-05-17 14:47:168801 uint32 data_size = bucket->size();
8802 GLsizei imageSize = data_size;
8803 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:288804 if (!data) {
8805 return error::kInvalidArguments;
8806 }
[email protected]9438b012010-06-15 22:55:058807 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518808 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:538809 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:168810 return error::kNoError;
8811 }
[email protected]9438b012010-06-15 22:55:058812 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518813 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8814 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:058815 return error::kNoError;
8816 }
[email protected]b6140d02010-05-17 14:47:168817 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518818 LOCAL_SET_GL_ERROR(
8819 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:168820 return error::kNoError;
8821 }
8822 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518823 LOCAL_SET_GL_ERROR(
8824 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:168825 return error::kNoError;
8826 }
8827 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:518828 LOCAL_SET_GL_ERROR(
8829 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:168830 return error::kNoError;
8831 }
[email protected]cadde4a2010-07-31 17:10:438832 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:168833 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8834 return error::kNoError;
8835}
8836
vmiuracd108592014-09-08 14:36:348837error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size,
8838 const void* cmd_data) {
8839 const gles2::cmds::TexImage2D& c =
8840 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:138841 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
8842 "width", c.width, "height", c.height);
[email protected]c986af502013-08-14 01:04:448843 // Set as failed for now, but if it successed, this will be set to not failed.
8844 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:198845 GLenum target = static_cast<GLenum>(c.target);
8846 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:448847 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8848 // for internalformat.
8849 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198850 GLsizei width = static_cast<GLsizei>(c.width);
8851 GLsizei height = static_cast<GLsizei>(c.height);
8852 GLint border = static_cast<GLint>(c.border);
8853 GLenum format = static_cast<GLenum>(c.format);
8854 GLenum type = static_cast<GLenum>(c.type);
8855 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8856 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188857 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348858 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428859 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
8860 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:188861 return error::kOutOfBounds;
8862 }
[email protected]b9849abf2009-11-25 19:13:198863 const void* pixels = NULL;
8864 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8865 pixels = GetSharedMemoryAs<const void*>(
8866 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468867 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148868 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198869 }
8870 }
[email protected]f598f422012-12-07 08:30:038871
[email protected]c986af502013-08-14 01:04:448872 TextureManager::DoTextImage2DArguments args = {
8873 target, level, internal_format, width, height, border, format, type,
8874 pixels, pixels_size};
8875 texture_manager()->ValidateAndDoTexImage2D(
8876 &texture_state_, &state_, &framebuffer_state_, args);
vmiura8266ca72014-09-09 21:37:008877
8878 // This may be a slow command. Exit command processing to allow for
8879 // context preemption and GPU watchdog checks.
8880 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:038881 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198882}
8883
zmobcadd6592015-01-08 20:13:428884error::Error GLES2DecoderImpl::HandleTexImage3D(uint32 immediate_data_size,
8885 const void* cmd_data) {
8886 // TODO(zmo): Unsafe ES3 API.
8887 if (!unsafe_es3_apis_enabled())
8888 return error::kUnknownCommand;
8889
8890 const gles2::cmds::TexImage3D& c =
8891 *static_cast<const gles2::cmds::TexImage3D*>(cmd_data);
8892 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage3D",
8893 "widthXheight", c.width * c.height, "depth", c.depth);
8894 GLenum target = static_cast<GLenum>(c.target);
8895 GLint level = static_cast<GLint>(c.level);
8896 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8897 GLsizei width = static_cast<GLsizei>(c.width);
8898 GLsizei height = static_cast<GLsizei>(c.height);
8899 GLsizei depth = static_cast<GLsizei>(c.depth);
8900 GLint border = static_cast<GLint>(c.border);
8901 GLenum format = static_cast<GLenum>(c.format);
8902 GLenum type = static_cast<GLenum>(c.type);
8903 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8904 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
8905 uint32 pixels_size;
8906 if (!GLES2Util::ComputeImageDataSizes(
8907 width, height, depth, format, type, state_.unpack_alignment, &pixels_size,
8908 NULL, NULL)) {
8909 return error::kOutOfBounds;
8910 }
8911 const void* pixels = NULL;
8912 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8913 pixels = GetSharedMemoryAs<const void*>(
8914 pixels_shm_id, pixels_shm_offset, pixels_size);
8915 if (!pixels) {
8916 return error::kOutOfBounds;
8917 }
8918 }
8919
8920 glTexImage3D(target, level, internal_format, width, height, depth, border,
8921 format, type, pixels);
8922
8923 // This may be a slow command. Exit command processing to allow for
8924 // context preemption and GPU watchdog checks.
8925 ExitCommandProcessingEarly();
8926 return error::kNoError;
8927}
8928
[email protected]cadde4a2010-07-31 17:10:438929void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8930 GLenum target,
8931 GLint level,
8932 GLint xoffset,
8933 GLint yoffset,
8934 GLsizei width,
8935 GLsizei height,
8936 GLenum format,
8937 GLsizei image_size,
8938 const void * data) {
[email protected]c986af502013-08-14 01:04:448939 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8940 &state_, target);
[email protected]370eaf12013-05-18 09:19:498941 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518942 LOCAL_SET_GL_ERROR(
8943 GL_INVALID_OPERATION,
8944 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438945 return;
8946 }
[email protected]370eaf12013-05-18 09:19:498947 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438948 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:528949 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078950 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518951 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528952 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438953 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:528954 return;
8955 }
8956 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:518957 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528958 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438959 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:528960 return;
8961 }
[email protected]02965c22013-03-09 02:40:078962 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528963 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518964 LOCAL_SET_GL_ERROR(
8965 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438966 return;
8967 }
[email protected]ad84a3a2012-06-08 21:42:438968
8969 if (!ValidateCompressedTexFuncData(
8970 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8971 !ValidateCompressedTexSubDimensions(
8972 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:078973 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:438974 return;
8975 }
8976
8977
[email protected]0d6bfdc2011-11-02 01:32:208978 // Note: There is no need to deal with texture cleared tracking here
8979 // because the validation above means you can only get here if the level
8980 // is already a matching compressed format and in that case
8981 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:438982 glCompressedTexSubImage2D(
8983 target, level, xoffset, yoffset, width, height, format, image_size, data);
vmiura8266ca72014-09-09 21:37:008984
8985 // This may be a slow command. Exit command processing to allow for
8986 // context preemption and GPU watchdog checks.
8987 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438988}
8989
[email protected]6e288612010-12-21 20:45:038990static void Clip(
8991 GLint start, GLint range, GLint sourceRange,
8992 GLint* out_start, GLint* out_range) {
8993 DCHECK(out_start);
8994 DCHECK(out_range);
8995 if (start < 0) {
8996 range += start;
8997 start = 0;
8998 }
8999 GLint end = start + range;
9000 if (end > sourceRange) {
9001 range -= end - sourceRange;
9002 }
9003 *out_start = start;
9004 *out_range = range;
9005}
9006
[email protected]cadde4a2010-07-31 17:10:439007void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:449008 GLenum target,
9009 GLint level,
9010 GLenum internal_format,
9011 GLint x,
9012 GLint y,
9013 GLsizei width,
9014 GLsizei height,
9015 GLint border) {
[email protected]09e17272012-11-30 10:30:449016 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:449017 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9018 &state_, target);
[email protected]370eaf12013-05-18 09:19:499019 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519020 LOCAL_SET_GL_ERROR(
9021 GL_INVALID_OPERATION,
9022 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439023 return;
9024 }
[email protected]370eaf12013-05-18 09:19:499025 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079026 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519027 LOCAL_SET_GL_ERROR(
9028 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]cedee332014-05-23 07:07:539029 return;
[email protected]97dc7cbe2011-12-06 17:26:179030 }
[email protected]80eb6b52012-01-19 00:14:419031 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:189032 border != 0) {
[email protected]ab09b612013-03-11 22:11:519033 LOCAL_SET_GL_ERROR(
9034 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:189035 return;
9036 }
[email protected]17a961192014-02-14 15:20:529037 if (!texture_manager()->ValidateFormatAndTypeCombination(
9038 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
9039 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:009040 return;
9041 }
[email protected]f5719fb2010-08-04 18:27:189042
[email protected]9edc6b22010-12-23 02:00:269043 // Check we have compatible formats.
9044 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
9045 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
9046 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
9047
9048 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:519049 LOCAL_SET_GL_ERROR(
9050 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:269051 return;
9052 }
9053
[email protected]81375742012-06-08 00:04:009054 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519055 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009056 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:269057 "glCopyTexImage2D", "can not be used with depth or stencil textures");
9058 return;
9059 }
9060
9061 uint32 estimated_size = 0;
9062 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429063 width, height, 1, internal_format, GL_UNSIGNED_BYTE,
9064 state_.unpack_alignment, &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:519065 LOCAL_SET_GL_ERROR(
9066 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269067 return;
9068 }
9069
9070 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519071 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:009072 return;
9073 }
9074
[email protected]2ea5950d2014-07-09 18:20:349075 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) {
9076 return;
9077 }
9078
zmo383512cf2014-10-14 00:11:009079 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
9080 LOCAL_SET_GL_ERROR(
9081 GL_INVALID_OPERATION,
9082 "glCopyTexImage2D", "source and destination textures are the same");
9083 return;
9084 }
9085
[email protected]a0b78dc2011-11-11 10:43:109086 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
9087 return;
9088 }
9089
[email protected]ab09b612013-03-11 22:11:519090 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:279091 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:039092 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:269093
[email protected]02965c22013-03-09 02:40:079094 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:449095 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:469096 }
9097
[email protected]9edc6b22010-12-23 02:00:269098 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:039099 GLint copyX = 0;
9100 GLint copyY = 0;
9101 GLint copyWidth = 0;
9102 GLint copyHeight = 0;
9103 Clip(x, width, size.width(), &copyX, &copyWidth);
9104 Clip(y, height, size.height(), &copyY, &copyHeight);
9105
9106 if (copyX != x ||
9107 copyY != y ||
9108 copyWidth != width ||
9109 copyHeight != height) {
9110 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:209111 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:079112 texture->service_id(), texture->target(),
[email protected]d8e6c9242014-02-20 16:56:259113 target, level, internal_format, internal_format, GL_UNSIGNED_BYTE,
9114 width, height, texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:519115 LOCAL_SET_GL_ERROR(
9116 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:039117 return;
9118 }
[email protected]6e288612010-12-21 20:45:039119 if (copyHeight > 0 && copyWidth > 0) {
9120 GLint dx = copyX - x;
9121 GLint dy = copyY - y;
9122 GLint destX = dx;
9123 GLint destY = dy;
[email protected]00c2cf92014-03-14 00:08:379124 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039125 glCopyTexSubImage2D(target, level,
9126 destX, destY, copyX, copyY,
9127 copyWidth, copyHeight);
9128 }
9129 } else {
[email protected]00c2cf92014-03-14 00:08:379130 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039131 glCopyTexImage2D(target, level, internal_format,
9132 copyX, copyY, copyWidth, copyHeight, border);
9133 }
[email protected]ab09b612013-03-11 22:11:519134 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:439135 if (error == GL_NO_ERROR) {
9136 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499137 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:209138 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:439139 }
vmiura8266ca72014-09-09 21:37:009140
9141 // This may be a slow command. Exit command processing to allow for
9142 // context preemption and GPU watchdog checks.
9143 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439144}
9145
9146void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:449147 GLenum target,
9148 GLint level,
9149 GLint xoffset,
9150 GLint yoffset,
9151 GLint x,
9152 GLint y,
9153 GLsizei width,
9154 GLsizei height) {
[email protected]09e17272012-11-30 10:30:449155 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:449156 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9157 &state_, target);
[email protected]370eaf12013-05-18 09:19:499158 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519159 LOCAL_SET_GL_ERROR(
9160 GL_INVALID_OPERATION,
9161 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439162 return;
9163 }
[email protected]370eaf12013-05-18 09:19:499164 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:439165 GLenum type = 0;
9166 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:079167 if (!texture->GetLevelType(target, level, &type, &format) ||
9168 !texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529169 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519170 LOCAL_SET_GL_ERROR(
9171 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:439172 return;
9173 }
[email protected]85a4ac22013-05-31 01:58:479174 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:519175 LOCAL_SET_GL_ERROR(
9176 GL_INVALID_OPERATION,
9177 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:599178 return;
9179 }
[email protected]9edc6b22010-12-23 02:00:269180
9181 // Check we have compatible formats.
9182 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
9183 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
9184 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
9185
[email protected]2d3765b2012-10-03 00:31:079186 if (!channels_needed ||
9187 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:519188 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439189 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:269190 return;
9191 }
9192
[email protected]81375742012-06-08 00:04:009193 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519194 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009195 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439196 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:009197 return;
9198 }
9199
[email protected]2ea5950d2014-07-09 18:20:349200 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) {
9201 return;
9202 }
9203
zmo383512cf2014-10-14 00:11:009204 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
9205 LOCAL_SET_GL_ERROR(
9206 GL_INVALID_OPERATION,
9207 "glCopyTexSubImage2D", "source and destination textures are the same");
9208 return;
9209 }
9210
[email protected]a0b78dc2011-11-11 10:43:109211 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
9212 return;
9213 }
9214
[email protected]de26b3c2011-08-03 21:54:279215 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:039216 gfx::Size size = GetBoundReadFrameBufferSize();
9217 GLint copyX = 0;
9218 GLint copyY = 0;
9219 GLint copyWidth = 0;
9220 GLint copyHeight = 0;
9221 Clip(x, width, size.width(), &copyX, &copyWidth);
9222 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:209223
dongseong.hwang351519f2015-01-21 14:33:599224 if (xoffset != 0 || yoffset != 0 || width != size.width() ||
9225 height != size.height()) {
9226 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target,
9227 level)) {
9228 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D",
9229 "dimensions too big");
9230 return;
9231 }
9232 } else {
9233 // Write all pixels in below.
9234 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]0d6bfdc2011-11-02 01:32:209235 }
9236
[email protected]6e288612010-12-21 20:45:039237 if (copyX != x ||
9238 copyY != y ||
9239 copyWidth != width ||
9240 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:209241 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:039242 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:349243 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429244 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
[email protected]e259eb412012-10-13 05:47:249245 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:519246 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439247 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:039248 return;
9249 }
[email protected]40d90a22013-04-09 03:39:559250 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:039251 memset(zero.get(), 0, pixels_size);
[email protected]00c2cf92014-03-14 00:08:379252 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039253 glTexSubImage2D(
9254 target, level, xoffset, yoffset, width, height,
9255 format, type, zero.get());
9256 }
[email protected]0d6bfdc2011-11-02 01:32:209257
[email protected]6e288612010-12-21 20:45:039258 if (copyHeight > 0 && copyWidth > 0) {
9259 GLint dx = copyX - x;
9260 GLint dy = copyY - y;
9261 GLint destX = xoffset + dx;
9262 GLint destY = yoffset + dy;
[email protected]00c2cf92014-03-14 00:08:379263 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039264 glCopyTexSubImage2D(target, level,
9265 destX, destY, copyX, copyY,
9266 copyWidth, copyHeight);
9267 }
vmiura8266ca72014-09-09 21:37:009268
9269 // This may be a slow command. Exit command processing to allow for
9270 // context preemption and GPU watchdog checks.
9271 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439272}
9273
[email protected]f598f422012-12-07 08:30:039274bool GLES2DecoderImpl::ValidateTexSubImage2D(
9275 error::Error* error,
9276 const char* function_name,
9277 GLenum target,
9278 GLint level,
9279 GLint xoffset,
9280 GLint yoffset,
9281 GLsizei width,
9282 GLsizei height,
9283 GLenum format,
9284 GLenum type,
9285 const void * data) {
9286 (*error) = error::kNoError;
9287 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:519288 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:039289 return false;
9290 }
9291 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:519292 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:039293 return false;
9294 }
9295 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:519296 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:039297 return false;
9298 }
[email protected]c986af502013-08-14 01:04:449299 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9300 &state_, target);
[email protected]370eaf12013-05-18 09:19:499301 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519302 LOCAL_SET_GL_ERROR(
9303 GL_INVALID_OPERATION,
9304 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:039305 return false;
[email protected]cadde4a2010-07-31 17:10:439306 }
[email protected]370eaf12013-05-18 09:19:499307 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:529308 GLenum current_type = 0;
9309 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:079310 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:519311 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:039312 GL_INVALID_OPERATION, function_name, "level does not exist.");
9313 return false;
[email protected]df6cf1ad2011-01-29 01:20:529314 }
[email protected]17a961192014-02-14 15:20:529315 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
9316 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:039317 return false;
[email protected]df6cf1ad2011-01-29 01:20:529318 }
9319 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:519320 LOCAL_SET_GL_ERROR(
9321 GL_INVALID_OPERATION,
9322 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:039323 return false;
[email protected]df6cf1ad2011-01-29 01:20:529324 }
[email protected]85a4ac22013-05-31 01:58:479325 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:519326 LOCAL_SET_GL_ERROR(
9327 GL_INVALID_OPERATION,
9328 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:599329 return false;
9330 }
[email protected]02965c22013-03-09 02:40:079331 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529332 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519333 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:039334 return false;
[email protected]cadde4a2010-07-31 17:10:439335 }
[email protected]81375742012-06-08 00:04:009336 if ((GLES2Util::GetChannelsForFormat(format) &
9337 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519338 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009339 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:039340 function_name, "can not supply data for depth or stencil textures");
9341 return false;
[email protected]81375742012-06-08 00:04:009342 }
[email protected]f598f422012-12-07 08:30:039343 if (data == NULL) {
9344 (*error) = error::kOutOfBounds;
9345 return false;
9346 }
9347 return true;
9348}
[email protected]81375742012-06-08 00:04:009349
[email protected]f598f422012-12-07 08:30:039350error::Error GLES2DecoderImpl::DoTexSubImage2D(
9351 GLenum target,
9352 GLint level,
9353 GLint xoffset,
9354 GLint yoffset,
9355 GLsizei width,
9356 GLsizei height,
9357 GLenum format,
9358 GLenum type,
9359 const void * data) {
9360 error::Error error = error::kNoError;
9361 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
9362 xoffset, yoffset, width, height, format, type, data)) {
9363 return error;
9364 }
[email protected]c986af502013-08-14 01:04:449365 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9366 &state_, target);
[email protected]370eaf12013-05-18 09:19:499367 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:159368 GLsizei tex_width = 0;
9369 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:079370 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:159371 DCHECK(ok);
9372 if (xoffset != 0 || yoffset != 0 ||
9373 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:499374 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
9375 target, level)) {
[email protected]ab09b612013-03-11 22:11:519376 LOCAL_SET_GL_ERROR(
9377 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:039378 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:309379 }
[email protected]c986af502013-08-14 01:04:449380 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159381 glTexSubImage2D(
9382 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:039383 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:209384 }
[email protected]4502e6492011-12-14 19:39:159385
[email protected]345ba902013-11-14 21:39:009386 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
[email protected]c986af502013-08-14 01:04:449387 !texture->IsImmutable()) {
9388 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:259389 GLenum internal_format;
9390 GLenum tex_type;
9391 texture->GetLevelType(target, level, &tex_type, &internal_format);
9392 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
9393 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:389394 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:259395 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:159396 } else {
[email protected]c986af502013-08-14 01:04:449397 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159398 glTexSubImage2D(
9399 target, level, xoffset, yoffset, width, height, format, type, data);
9400 }
[email protected]370eaf12013-05-18 09:19:499401 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
vmiura8266ca72014-09-09 21:37:009402
9403 // This may be a slow command. Exit command processing to allow for
9404 // context preemption and GPU watchdog checks.
9405 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:039406 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:439407}
9408
vmiuracd108592014-09-08 14:36:349409error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
9410 const void* cmd_data) {
9411 const gles2::cmds::TexSubImage2D& c =
9412 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:139413 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
9414 "width", c.width, "height", c.height);
[email protected]b493ee622011-04-13 23:52:009415 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:449416 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:009417 return error::kNoError;
9418
9419 GLenum target = static_cast<GLenum>(c.target);
9420 GLint level = static_cast<GLint>(c.level);
9421 GLint xoffset = static_cast<GLint>(c.xoffset);
9422 GLint yoffset = static_cast<GLint>(c.yoffset);
9423 GLsizei width = static_cast<GLsizei>(c.width);
9424 GLsizei height = static_cast<GLsizei>(c.height);
9425 GLenum format = static_cast<GLenum>(c.format);
9426 GLenum type = static_cast<GLenum>(c.type);
9427 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:349428 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429429 width, height, 1, format, type, state_.unpack_alignment, &data_size,
[email protected]e259eb412012-10-13 05:47:249430 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:009431 return error::kOutOfBounds;
9432 }
9433 const void* pixels = GetSharedMemoryAs<const void*>(
9434 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:039435 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:009436 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:009437}
9438
zmobcadd6592015-01-08 20:13:429439// TODO(zmo): Remove the below stub once we add the real function binding.
9440// Currently it's missing due to a gmock limitation.
9441static void glTexSubImage3D(
9442 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
9443 GLsizei height, GLsizei width, GLsizei depth, GLenum format, GLenum type,
9444 const void* pixels) {
9445 NOTIMPLEMENTED();
9446}
9447
9448error::Error GLES2DecoderImpl::HandleTexSubImage3D(uint32 immediate_data_size,
9449 const void* cmd_data) {
9450 // TODO(zmo): Unsafe ES3 API.
9451 if (!unsafe_es3_apis_enabled())
9452 return error::kUnknownCommand;
9453
9454 const gles2::cmds::TexSubImage3D& c =
9455 *static_cast<const gles2::cmds::TexSubImage3D*>(cmd_data);
9456 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage3D",
9457 "widthXheight", c.width * c.height, "depth", c.depth);
9458 GLenum target = static_cast<GLenum>(c.target);
9459 GLint level = static_cast<GLint>(c.level);
9460 GLint xoffset = static_cast<GLint>(c.xoffset);
9461 GLint yoffset = static_cast<GLint>(c.yoffset);
9462 GLint zoffset = static_cast<GLint>(c.zoffset);
9463 GLsizei width = static_cast<GLsizei>(c.width);
9464 GLsizei height = static_cast<GLsizei>(c.height);
9465 GLsizei depth = static_cast<GLsizei>(c.depth);
9466 GLenum format = static_cast<GLenum>(c.format);
9467 GLenum type = static_cast<GLenum>(c.type);
9468 uint32 data_size;
9469 if (!GLES2Util::ComputeImageDataSizes(
9470 width, height, depth, format, type, state_.unpack_alignment, &data_size,
9471 NULL, NULL)) {
9472 return error::kOutOfBounds;
9473 }
9474 const void* pixels = GetSharedMemoryAs<const void*>(
9475 c.pixels_shm_id, c.pixels_shm_offset, data_size);
9476 glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height,
9477 depth, format, type, pixels);
9478 return error::kNoError;
9479}
9480
[email protected]f7a64ee2010-02-01 22:24:149481error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
vmiuracd108592014-09-08 14:36:349482 uint32 immediate_data_size,
9483 const void* cmd_data) {
9484 const gles2::cmds::GetVertexAttribPointerv& c =
9485 *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data);
[email protected]8bf5a3e2010-01-29 04:21:369486 GLuint index = static_cast<GLuint>(c.index);
9487 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:359488 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:259489 Result* result = GetSharedMemoryAs<Result*>(
9490 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:369491 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:149492 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:369493 }
[email protected]07d0cc82010-02-17 04:51:409494 // Check that the client initialized the result.
9495 if (result->size != 0) {
9496 return error::kInvalidArguments;
9497 }
[email protected]9438b012010-06-15 22:55:059498 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:519499 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9500 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:149501 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369502 }
[email protected]3916c97e2010-02-25 03:20:509503 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:519504 LOCAL_SET_GL_ERROR(
9505 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:149506 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369507 }
[email protected]0bfd9882010-02-05 23:02:259508 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:089509 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:359510 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:149511 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329512}
9513
[email protected]f7b85372010-02-03 01:11:379514bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:429515 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:379516 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:129517 error::Error* error, GLint* real_location,
9518 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:109519 DCHECK(error);
9520 DCHECK(service_id);
9521 DCHECK(result_pointer);
9522 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:129523 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:379524 *error = error::kNoError;
9525 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:259526 SizedResult<GLint>* result;
9527 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9528 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
9529 if (!result) {
[email protected]f7b85372010-02-03 01:11:379530 *error = error::kOutOfBounds;
9531 return false;
9532 }
[email protected]0bfd9882010-02-05 23:02:259533 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:379534 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:259535 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:429536 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
9537 if (!program) {
[email protected]ae51d192010-04-27 00:48:039538 return false;
9539 }
[email protected]df37b9932013-03-08 05:21:429540 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:379541 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:519542 LOCAL_SET_GL_ERROR(
9543 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:379544 return false;
9545 }
[email protected]df37b9932013-03-08 05:21:429546 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:369547 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:359548 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429549 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:129550 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:369551 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:379552 // No such location.
[email protected]ab09b612013-03-11 22:11:519553 LOCAL_SET_GL_ERROR(
9554 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:379555 return false;
9556 }
[email protected]43c2f1f2011-03-25 18:35:369557 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:509558 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:379559 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:519560 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:379561 return false;
9562 }
[email protected]0bfd9882010-02-05 23:02:259563 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9564 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
9565 if (!result) {
[email protected]f7b85372010-02-03 01:11:379566 *error = error::kOutOfBounds;
9567 return false;
9568 }
[email protected]0bfd9882010-02-05 23:02:259569 result->size = size;
[email protected]939e7362010-05-13 20:49:109570 *result_type = type;
[email protected]f7b85372010-02-03 01:11:379571 return true;
9572}
9573
vmiuracd108592014-09-08 14:36:349574error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size,
9575 const void* cmd_data) {
9576 const gles2::cmds::GetUniformiv& c =
9577 *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379578 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339579 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379580 GLuint service_id;
[email protected]939e7362010-05-13 20:49:109581 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:129582 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379583 Error error;
[email protected]0bfd9882010-02-05 23:02:259584 void* result;
[email protected]f7b85372010-02-03 01:11:379585 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129586 program, fake_location, c.params_shm_id, c.params_shm_offset,
9587 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:259588 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:129589 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:359590 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:379591 }
9592 return error;
[email protected]96449d2c2009-11-25 00:01:329593}
9594
vmiuracd108592014-09-08 14:36:349595error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size,
9596 const void* cmd_data) {
9597 const gles2::cmds::GetUniformfv& c =
9598 *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379599 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339600 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379601 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:129602 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379603 Error error;
[email protected]ed9f9cd2013-02-27 21:12:359604 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:109605 Result* result;
9606 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:379607 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129608 program, fake_location, c.params_shm_id, c.params_shm_offset,
9609 &error, &real_location, &service_id,
9610 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:109611 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
9612 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
9613 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:559614 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:129615 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:109616 GLfloat* dst = result->GetData();
9617 for (GLsizei ii = 0; ii < num_values; ++ii) {
9618 dst[ii] = (temp[ii] != 0);
9619 }
9620 } else {
[email protected]1b0a6752012-02-22 03:44:129621 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:109622 }
[email protected]f7b85372010-02-03 01:11:379623 }
9624 return error;
[email protected]96449d2c2009-11-25 00:01:329625}
9626
[email protected]f7a64ee2010-02-01 22:24:149627error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
vmiuracd108592014-09-08 14:36:349628 uint32 immediate_data_size,
9629 const void* cmd_data) {
9630 const gles2::cmds::GetShaderPrecisionFormat& c =
9631 *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259632 GLenum shader_type = static_cast<GLenum>(c.shadertype);
9633 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:359634 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:259635 Result* result = GetSharedMemoryAs<Result*>(
9636 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9637 if (!result) {
9638 return error::kOutOfBounds;
9639 }
[email protected]07d0cc82010-02-17 04:51:409640 // Check that the client initialized the result.
9641 if (result->success != 0) {
9642 return error::kInvalidArguments;
9643 }
[email protected]9438b012010-06-15 22:55:059644 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:519645 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539646 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:299647 return error::kNoError;
9648 }
[email protected]9438b012010-06-15 22:55:059649 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:519650 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539651 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:299652 return error::kNoError;
9653 }
9654
9655 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:409656
[email protected]46c86752013-05-21 05:08:399657 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:409658 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:219659 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:409660
9661 result->min_range = range[0];
9662 result->max_range = range[1];
9663 result->precision = precision;
9664
[email protected]f7a64ee2010-02-01 22:24:149665 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329666}
9667
[email protected]f7a64ee2010-02-01 22:24:149668error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
vmiuracd108592014-09-08 14:36:349669 uint32 immediate_data_size,
9670 const void* cmd_data) {
9671 const gles2::cmds::GetAttachedShaders& c =
9672 *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259673 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:429674 GLuint program_id = static_cast<GLuint>(c.program);
9675 Program* program = GetProgramInfoNotShader(
9676 program_id, "glGetAttachedShaders");
9677 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259678 return error::kNoError;
9679 }
[email protected]ed9f9cd2013-02-27 21:12:359680 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:259681 uint32 max_count = Result::ComputeMaxResults(result_size);
9682 Result* result = GetSharedMemoryAs<Result*>(
9683 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
9684 if (!result) {
9685 return error::kOutOfBounds;
9686 }
[email protected]07d0cc82010-02-17 04:51:409687 // Check that the client initialized the result.
9688 if (result->size != 0) {
9689 return error::kInvalidArguments;
9690 }
[email protected]0bfd9882010-02-05 23:02:259691 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:039692 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:429693 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:259694 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:039695 if (!shader_manager()->GetClientId(result->GetData()[ii],
9696 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:259697 NOTREACHED();
9698 return error::kGenericError;
9699 }
9700 }
9701 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:149702 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329703}
9704
[email protected]f7a64ee2010-02-01 22:24:149705error::Error GLES2DecoderImpl::HandleGetActiveUniform(
vmiuracd108592014-09-08 14:36:349706 uint32 immediate_data_size,
9707 const void* cmd_data) {
9708 const gles2::cmds::GetActiveUniform& c =
9709 *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429710 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259711 GLuint index = c.index;
9712 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359713 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:259714 Result* result = GetSharedMemoryAs<Result*>(
9715 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9716 if (!result) {
9717 return error::kOutOfBounds;
9718 }
[email protected]07d0cc82010-02-17 04:51:409719 // Check that the client initialized the result.
9720 if (result->success != 0) {
9721 return error::kInvalidArguments;
9722 }
[email protected]df37b9932013-03-08 05:21:429723 Program* program = GetProgramInfoNotShader(
9724 program_id, "glGetActiveUniform");
9725 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259726 return error::kNoError;
9727 }
[email protected]ed9f9cd2013-02-27 21:12:359728 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429729 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:259730 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:519731 LOCAL_SET_GL_ERROR(
9732 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259733 return error::kNoError;
9734 }
9735 result->success = 1; // true.
9736 result->size = uniform_info->size;
9737 result->type = uniform_info->type;
9738 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299739 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149740 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329741}
9742
zmoa2b555d2015-02-06 23:50:399743error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockiv(
9744 uint32 immediate_data_size, const void* cmd_data) {
9745 if (!unsafe_es3_apis_enabled())
9746 return error::kUnknownCommand;
9747 const gles2::cmds::GetActiveUniformBlockiv& c =
9748 *static_cast<const gles2::cmds::GetActiveUniformBlockiv*>(cmd_data);
9749 GLuint program_id = c.program;
9750 GLuint index = static_cast<GLuint>(c.index);
9751 GLenum pname = static_cast<GLenum>(c.pname);
9752 Program* program = GetProgramInfoNotShader(
zmo8fab00c2015-02-07 02:45:059753 program_id, "glGetActiveUniformBlockiv");
zmoa2b555d2015-02-06 23:50:399754 if (!program) {
9755 return error::kNoError;
9756 }
9757 GLuint service_id = program->service_id();
9758 GLint link_status = GL_FALSE;
9759 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
9760 if (link_status != GL_TRUE) {
9761 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9762 "glGetActiveActiveUniformBlockiv", "program not linked");
9763 return error::kNoError;
9764 }
9765 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetActiveUniformBlockiv");
9766 GLsizei num_values = 1;
9767 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) {
9768 GLint num = 0;
9769 glGetActiveUniformBlockiv(
9770 service_id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &num);
9771 GLenum error = glGetError();
9772 if (error != GL_NO_ERROR) {
9773 // Assume this will the same error if calling with pname.
9774 LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", "");
9775 return error::kNoError;
9776 }
9777 num_values = static_cast<GLsizei>(num);
9778 }
9779 typedef cmds::GetActiveUniformBlockiv::Result Result;
9780 Result* result = GetSharedMemoryAs<Result*>(
9781 c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
9782 GLint* params = result ? result->GetData() : NULL;
9783 if (params == NULL) {
9784 return error::kOutOfBounds;
9785 }
9786 // Check that the client initialized the result.
9787 if (result->size != 0) {
9788 return error::kInvalidArguments;
9789 }
9790 glGetActiveUniformBlockiv(service_id, index, pname, params);
9791 GLenum error = glGetError();
9792 if (error == GL_NO_ERROR) {
9793 result->SetNumResults(num_values);
9794 } else {
9795 LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", "");
9796 }
9797 return error::kNoError;
9798}
9799
zmo4a16ff992015-02-05 22:18:419800error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockName(
9801 uint32 immediate_data_size, const void* cmd_data) {
9802 if (!unsafe_es3_apis_enabled())
9803 return error::kUnknownCommand;
9804 const gles2::cmds::GetActiveUniformBlockName& c =
9805 *static_cast<const gles2::cmds::GetActiveUniformBlockName*>(cmd_data);
9806 GLuint program_id = c.program;
9807 GLuint index = c.index;
9808 uint32 name_bucket_id = c.name_bucket_id;
9809 typedef cmds::GetActiveUniformBlockName::Result Result;
9810 Result* result = GetSharedMemoryAs<Result*>(
9811 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9812 if (!result) {
9813 return error::kOutOfBounds;
9814 }
9815 // Check that the client initialized the result.
9816 if (*result != 0) {
9817 return error::kInvalidArguments;
9818 }
9819 Program* program = GetProgramInfoNotShader(
9820 program_id, "glGetActiveUniformBlockName");
9821 if (!program) {
9822 return error::kNoError;
9823 }
9824 GLuint service_id = program->service_id();
9825 GLint link_status = GL_FALSE;
9826 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
9827 if (link_status != GL_TRUE) {
9828 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9829 "glGetActiveActiveUniformBlockName", "program not linked");
9830 return error::kNoError;
9831 }
9832 GLint max_length = 0;
9833 glGetProgramiv(
9834 service_id, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_length);
9835 // Increase one so &buffer[0] is always valid.
9836 GLsizei buf_size = static_cast<GLsizei>(max_length) + 1;
9837 std::vector<char> buffer(buf_size);
9838 GLsizei length = 0;
9839 glGetActiveUniformBlockName(
9840 service_id, index, buf_size, &length, &buffer[0]);
9841 if (length == 0) {
9842 *result = 0;
9843 return error::kNoError;
9844 }
9845 *result = 1;
9846 Bucket* bucket = CreateBucket(name_bucket_id);
9847 DCHECK_GT(buf_size, length);
9848 DCHECK_EQ(0, buffer[length]);
9849 bucket->SetFromString(&buffer[0]);
9850 return error::kNoError;
9851}
9852
vmiuracd108592014-09-08 14:36:349853error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size,
9854 const void* cmd_data) {
9855 const gles2::cmds::GetActiveAttrib& c =
9856 *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429857 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259858 GLuint index = c.index;
9859 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359860 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:259861 Result* result = GetSharedMemoryAs<Result*>(
9862 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9863 if (!result) {
9864 return error::kOutOfBounds;
9865 }
[email protected]07d0cc82010-02-17 04:51:409866 // Check that the client initialized the result.
9867 if (result->success != 0) {
9868 return error::kInvalidArguments;
9869 }
[email protected]df37b9932013-03-08 05:21:429870 Program* program = GetProgramInfoNotShader(
9871 program_id, "glGetActiveAttrib");
9872 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259873 return error::kNoError;
9874 }
[email protected]ed9f9cd2013-02-27 21:12:359875 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:429876 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:259877 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:519878 LOCAL_SET_GL_ERROR(
9879 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259880 return error::kNoError;
9881 }
9882 result->success = 1; // true.
9883 result->size = attrib_info->size;
9884 result->type = attrib_info->type;
9885 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299886 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149887 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329888}
9889
vmiuracd108592014-09-08 14:36:349890error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size,
9891 const void* cmd_data) {
[email protected]b273e432010-04-12 17:23:589892#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:519893 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:589894 return error::kNoError;
9895#else
9896 GLsizei n = static_cast<GLsizei>(c.n);
9897 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:519898 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:589899 return error::kNoError;
9900 }
9901 GLsizei length = static_cast<GLsizei>(c.length);
9902 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:519903 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:589904 return error::kNoError;
9905 }
9906 uint32 data_size;
9907 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
9908 return error::kOutOfBounds;
9909 }
9910 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
9911 c.shaders_shm_id, c.shaders_shm_offset, data_size);
9912 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
9913 const void* binary = GetSharedMemoryAs<const void*>(
9914 c.binary_shm_id, c.binary_shm_offset, length);
9915 if (shaders == NULL || binary == NULL) {
9916 return error::kOutOfBounds;
9917 }
[email protected]0782b14b2014-05-24 13:04:169918 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]b273e432010-04-12 17:23:589919 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:429920 Shader* shader = GetShader(shaders[ii]);
9921 if (!shader) {
[email protected]ab09b612013-03-11 22:11:519922 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:589923 return error::kNoError;
9924 }
[email protected]df37b9932013-03-08 05:21:429925 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:589926 }
9927 // TODO(gman): call glShaderBinary
9928 return error::kNoError;
9929#endif
9930}
9931
[email protected]6d792ee12013-05-15 00:40:569932void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:499933 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:089934
[email protected]64ace852011-05-19 21:49:499935 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:429936 // TRACE_EVENT for gpu tests:
9937 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:429938 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:429939 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
9940 "width", (is_offscreen ? offscreen_size_.width() :
9941 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:569942 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:499943 "offscreen", is_offscreen,
9944 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:159945 {
[email protected]a36ed4832014-04-24 16:40:279946 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
[email protected]b2e92592014-01-10 15:47:159947 }
9948
dyenb547eff62015-01-17 00:14:569949 ScopedGPUTrace scoped_gpu_trace(gpu_tracer_.get(), kTraceDecoder,
9950 "gpu_toplevel", "SwapBuffer");
9951
[email protected]8f9b8dd2013-09-12 18:05:139952 bool is_tracing;
9953 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
9954 &is_tracing);
9955 if (is_tracing) {
9956 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
9957 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
9958 is_offscreen ? offscreen_size_ : surface_->GetSize());
9959 }
9960
[email protected]6217d392010-03-25 22:08:359961 // If offscreen then don't actually SwapBuffers to the display. Just copy
9962 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:499963 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:319964 TRACE_EVENT2("gpu", "Offscreen",
9965 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:539966 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
9967 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
9968 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
9969 // fix this.
[email protected]62e155e2012-10-23 22:43:159970 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:539971 offscreen_saved_frame_buffer_->Create();
9972 glFinish();
9973 }
9974
9975 // Allocate the offscreen saved color texture.
9976 DCHECK(offscreen_saved_color_format_);
9977 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:099978 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:539979
9980 offscreen_saved_frame_buffer_->AttachRenderTexture(
9981 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:059982 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
9983 if (offscreen_saved_frame_buffer_->CheckStatus() !=
9984 GL_FRAMEBUFFER_COMPLETE) {
9985 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
9986 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:569987 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
9988 return;
[email protected]f0cfe752013-01-14 01:09:059989 }
[email protected]1fb8c482011-08-31 01:01:539990
[email protected]f0cfe752013-01-14 01:09:059991 // Clear the offscreen color texture.
9992 // TODO(piman): Is this still necessary?
9993 {
9994 ScopedFrameBufferBinder binder(this,
9995 offscreen_saved_frame_buffer_->id());
9996 glClearColor(0, 0, 0, 0);
[email protected]454157e2014-05-03 02:49:459997 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
9998 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f0cfe752013-01-14 01:09:059999 glClear(GL_COLOR_BUFFER_BIT);
10000 RestoreClearState();
10001 }
[email protected]1fb8c482011-08-31 01:01:5310002 }
10003
10004 UpdateParentTextureInfo();
10005 }
10006
[email protected]f0cfe752013-01-14 01:09:0510007 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:5610008 return;
[email protected]ab09b612013-03-11 22:11:5110009 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010010 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:3510011
[email protected]34ff8b0c2010-10-01 20:06:0210012 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:1310013 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:2710014 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:4810015 } else {
[email protected]069944672012-04-25 20:52:2310016 ScopedFrameBufferBinder binder(this,
10017 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:1310018
[email protected]069944672012-04-25 20:52:2310019 if (offscreen_target_buffer_preserved_) {
10020 // Copy the target frame buffer to the saved offscreen texture.
10021 offscreen_saved_color_texture_->Copy(
10022 offscreen_saved_color_texture_->size(),
10023 offscreen_saved_color_format_);
10024 } else {
10025 // Flip the textures in the parent context via the texture manager.
10026 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:4910027 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:2310028 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:5610029
[email protected]069944672012-04-25 20:52:2310030 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
10031 offscreen_target_frame_buffer_->AttachRenderTexture(
10032 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:4810033 }
[email protected]069944672012-04-25 20:52:2310034
10035 // Ensure the side effects of the copy are visible to the parent
10036 // context. There is no need to do this for ANGLE because it uses a
10037 // single D3D device for all contexts.
zmo68fcdc62014-12-05 21:51:4910038 if (!feature_info_->gl_version_info().is_angle)
[email protected]069944672012-04-25 20:52:2310039 glFlush();
[email protected]0c8c9d22010-06-25 17:36:3910040 }
[email protected]6217d392010-03-25 22:08:3510041 } else {
[email protected]f62a5ab2011-05-23 20:34:1510042 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:0110043 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:5610044 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:0110045 }
[email protected]6217d392010-03-25 22:08:3510046 }
vmiura8266ca72014-09-09 21:37:0010047
10048 // This may be a slow command. Exit command processing to allow for
10049 // context preemption and GPU watchdog checks.
10050 ExitCommandProcessingEarly();
[email protected]6217d392010-03-25 22:08:3510051}
10052
bajones2345c1f2014-12-09 04:45:5110053void GLES2DecoderImpl::DoSwapInterval(int interval)
10054{
10055 context_->SetSwapInterval(interval);
10056}
10057
[email protected]d4239852011-08-12 04:51:2210058error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
vmiuracd108592014-09-08 14:36:3410059 uint32 immediate_data_size,
10060 const void* cmd_data) {
10061 const gles2::cmds::EnableFeatureCHROMIUM& c =
10062 *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data);
[email protected]b1d2dcb2010-05-17 19:24:1810063 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:2810064 if (!bucket || bucket->size() == 0) {
10065 return error::kInvalidArguments;
10066 }
[email protected]ed9f9cd2013-02-27 21:12:3510067 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:1810068 Result* result = GetSharedMemoryAs<Result*>(
10069 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10070 if (!result) {
10071 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:1010072 }
[email protected]b1d2dcb2010-05-17 19:24:1810073 // Check that the client initialized the result.
10074 if (*result != 0) {
10075 return error::kInvalidArguments;
10076 }
10077 std::string feature_str;
10078 if (!bucket->GetAsString(&feature_str)) {
10079 return error::kInvalidArguments;
10080 }
10081
10082 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:2210083 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:1810084 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:2210085 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
penghuang0140c182015-01-12 23:20:1210086 buffer_manager()->set_allow_fixed_attribs(true);
[email protected]8fbedc02010-11-18 18:43:4010087 // TODO(gman): decide how to remove the need for this const_cast.
10088 // I could make validators_ non const but that seems bad as this is the only
10089 // place it is needed. I could make some special friend class of validators
10090 // just to allow this to set them. That seems silly. I could refactor this
10091 // code to use the extension mechanism or the initialization attributes to
10092 // turn this feature on. Given that the only real point of this is to make
10093 // the conformance tests pass and given that there is lots of real work that
10094 // needs to be done it seems like refactoring for one to one of those
10095 // methods is a very low priority.
10096 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:0410097 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
10098 force_webgl_glsl_validation_ = true;
10099 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:1810100 } else {
10101 return error::kNoError;
10102 }
10103
10104 *result = 1; // true.
10105 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:1010106}
10107
[email protected]c2f8c8402010-12-06 18:07:2410108error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
10109 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:3410110 const void* cmd_data) {
10111 const gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
10112 *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
10113 cmd_data);
[email protected]c2f8c8402010-12-06 18:07:2410114 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:3510115 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:1910116 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:2410117 bucket->SetFromString(info->extensions().c_str());
10118 return error::kNoError;
10119}
10120
10121error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
vmiuracd108592014-09-08 14:36:3410122 uint32 immediate_data_size,
10123 const void* cmd_data) {
10124 const gles2::cmds::RequestExtensionCHROMIUM& c =
10125 *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data);
[email protected]c2f8c8402010-12-06 18:07:2410126 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:2810127 if (!bucket || bucket->size() == 0) {
10128 return error::kInvalidArguments;
10129 }
[email protected]c2f8c8402010-12-06 18:07:2410130 std::string feature_str;
10131 if (!bucket->GetAsString(&feature_str)) {
10132 return error::kInvalidArguments;
10133 }
10134
[email protected]4b7eba92013-01-08 02:23:5610135 bool desire_webgl_glsl_validation =
10136 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
10137 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:4910138 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:1310139 bool desire_draw_buffers = false;
[email protected]93c2fd82014-04-16 02:46:0610140 bool desire_shader_texture_lod = false;
[email protected]4b7eba92013-01-08 02:23:5610141 if (force_webgl_glsl_validation_) {
10142 desire_standard_derivatives =
10143 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:4910144 desire_frag_depth =
10145 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:1310146 desire_draw_buffers =
10147 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]93c2fd82014-04-16 02:46:0610148 desire_shader_texture_lod =
10149 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:0410150 }
10151
[email protected]4b7eba92013-01-08 02:23:5610152 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:4910153 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:1310154 desire_frag_depth != frag_depth_explicitly_enabled_ ||
10155 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:4910156 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
10157 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
10158 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:1310159 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]93c2fd82014-04-16 02:46:0610160 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
[email protected]c2f8c8402010-12-06 18:07:2410161 InitializeShaderTranslator();
10162 }
10163
[email protected]302ce6d2011-07-07 23:28:1110164 UpdateCapabilities();
10165
[email protected]c2f8c8402010-12-06 18:07:2410166 return error::kNoError;
10167}
10168
[email protected]2318d342011-07-11 22:27:4210169error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
vmiuracd108592014-09-08 14:36:3410170 uint32 immediate_data_size,
10171 const void* cmd_data) {
10172 const gles2::cmds::GetProgramInfoCHROMIUM& c =
10173 *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:4210174 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:4210175 uint32 bucket_id = c.bucket_id;
10176 Bucket* bucket = CreateBucket(bucket_id);
10177 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:4210178 Program* program = NULL;
10179 program = GetProgram(program_id);
10180 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:4610181 return error::kNoError;
[email protected]2318d342011-07-11 22:27:4210182 }
[email protected]df37b9932013-03-08 05:21:4210183 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:4210184 return error::kNoError;
10185}
10186
zmo4a16ff992015-02-05 22:18:4110187error::Error GLES2DecoderImpl::HandleGetUniformBlocksCHROMIUM(
10188 uint32 immediate_data_size, const void* cmd_data) {
10189 if (!unsafe_es3_apis_enabled())
10190 return error::kUnknownCommand;
10191 const gles2::cmds::GetUniformBlocksCHROMIUM& c =
10192 *static_cast<const gles2::cmds::GetUniformBlocksCHROMIUM*>(cmd_data);
10193 GLuint program_id = static_cast<GLuint>(c.program);
10194 uint32 bucket_id = c.bucket_id;
10195 Bucket* bucket = CreateBucket(bucket_id);
10196 bucket->SetSize(sizeof(UniformBlocksHeader)); // in case we fail.
10197 Program* program = NULL;
10198 program = GetProgram(program_id);
10199 if (!program || !program->IsValid()) {
10200 return error::kNoError;
10201 }
10202 program->GetUniformBlocks(bucket);
10203 return error::kNoError;
10204}
10205
zmo10842492015-02-12 00:44:1610206error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVarying(
10207 uint32 immediate_data_size,
10208 const void* cmd_data) {
10209 if (!unsafe_es3_apis_enabled())
10210 return error::kUnknownCommand;
10211 const gles2::cmds::GetTransformFeedbackVarying& c =
10212 *static_cast<const gles2::cmds::GetTransformFeedbackVarying*>(cmd_data);
10213 GLuint program_id = c.program;
10214 GLuint index = c.index;
10215 uint32 name_bucket_id = c.name_bucket_id;
10216 typedef cmds::GetTransformFeedbackVarying::Result Result;
10217 Result* result = GetSharedMemoryAs<Result*>(
10218 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10219 if (!result) {
10220 return error::kOutOfBounds;
10221 }
10222 // Check that the client initialized the result.
10223 if (result->success != 0) {
10224 return error::kInvalidArguments;
10225 }
10226 Program* program = GetProgramInfoNotShader(
10227 program_id, "glGetTransformFeedbackVarying");
10228 if (!program) {
10229 return error::kNoError;
10230 }
10231 GLuint service_id = program->service_id();
10232 GLint link_status = GL_FALSE;
10233 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
10234 if (link_status != GL_TRUE) {
10235 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10236 "glGetTransformFeedbackVarying", "program not linked");
10237 return error::kNoError;
10238 }
10239 GLint max_length = 0;
10240 glGetProgramiv(
10241 service_id, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &max_length);
10242 max_length = std::max(1, max_length);
10243 std::vector<char> buffer(max_length);
10244 GLsizei length = 0;
10245 GLsizei size = 0;
10246 GLenum type = 0;
10247 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetTransformFeedbackVarying");
10248 glGetTransformFeedbackVarying(
10249 service_id, index, max_length, &length, &size, &type, &buffer[0]);
10250 GLenum error = glGetError();
10251 if (error != GL_NO_ERROR) {
10252 LOCAL_SET_GL_ERROR(error, "glGetTransformFeedbackVarying", "");
10253 return error::kNoError;
10254 }
10255 result->success = 1; // true.
10256 result->size = static_cast<int32_t>(size);
10257 result->type = static_cast<uint32_t>(type);
10258 Bucket* bucket = CreateBucket(name_bucket_id);
10259 DCHECK(length >= 0 && length < max_length);
10260 buffer[length] = '\0'; // Just to be safe.
10261 bucket->SetFromString(&buffer[0]);
10262 return error::kNoError;
10263}
10264
10265error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVaryingsCHROMIUM(
10266 uint32 immediate_data_size, const void* cmd_data) {
10267 if (!unsafe_es3_apis_enabled())
10268 return error::kUnknownCommand;
10269 const gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM& c =
10270 *static_cast<const gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM*>(
10271 cmd_data);
10272 GLuint program_id = static_cast<GLuint>(c.program);
10273 uint32 bucket_id = c.bucket_id;
10274 Bucket* bucket = CreateBucket(bucket_id);
10275 bucket->SetSize(sizeof(TransformFeedbackVaryingsHeader)); // in case we fail.
10276 Program* program = NULL;
10277 program = GetProgram(program_id);
10278 if (!program || !program->IsValid()) {
10279 return error::kNoError;
10280 }
10281 program->GetTransformFeedbackVaryings(bucket);
10282 return error::kNoError;
10283}
10284
[email protected]38d139d2011-07-14 00:38:4310285error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
10286 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:4310287 case GL_NO_ERROR:
10288 // TODO(kbr): improve the precision of the error code in this case.
10289 // Consider delegating to context for error code if MakeCurrent fails.
10290 return error::kUnknown;
10291 case GL_GUILTY_CONTEXT_RESET_ARB:
10292 return error::kGuilty;
10293 case GL_INNOCENT_CONTEXT_RESET_ARB:
10294 return error::kInnocent;
10295 case GL_UNKNOWN_CONTEXT_RESET_ARB:
10296 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:4310297 }
10298
10299 NOTREACHED();
10300 return error::kUnknown;
10301}
10302
jbauman7a059312014-10-16 19:30:5410303void GLES2DecoderImpl::MaybeExitOnContextLost() {
10304 // Some D3D drivers cannot recover from device lost in the GPU process
10305 // sandbox. Allow a new GPU process to launch.
10306 if (workarounds().exit_on_context_lost) {
10307 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
10308 << " a D3D device in the Chrome GPU process sandbox.";
10309#if defined(OS_WIN)
10310 base::win::SetShouldCrashOnProcessDetach(false);
10311#endif
10312 exit(0);
10313 }
10314}
10315
[email protected]38d139d2011-07-14 00:38:4310316bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:0910317 if (reset_status_ != GL_NO_ERROR) {
jbauman7a059312014-10-16 19:30:5410318 MaybeExitOnContextLost();
[email protected]c4485aad62012-12-17 10:19:0910319 return true;
10320 }
dongseong.hwange1cb2aa2015-02-11 09:33:3310321 if (IsRobustnessSupported()) {
10322 GLenum status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:4310323 if (status != GL_NO_ERROR) {
10324 // The graphics card was reset. Signal a lost context to the application.
10325 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:2210326 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:4310327 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:0910328 << " context lost via ARB/EXT_robustness. Reset status = "
10329 << GLES2Util::GetStringEnum(status);
jbauman7a059312014-10-16 19:30:5410330 MaybeExitOnContextLost();
[email protected]38d139d2011-07-14 00:38:4310331 return true;
10332 }
10333 }
10334 return false;
10335}
10336
[email protected]93a7d98f2013-07-11 00:04:2210337bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
10338 return WasContextLost() && reset_by_robustness_extension_;
10339}
10340
[email protected]c4485aad62012-12-17 10:19:0910341void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
10342 // Only loses the context once.
10343 if (reset_status_ != GL_NO_ERROR) {
10344 return;
10345 }
10346
oetuaho37cc50e2014-10-31 11:19:2010347 if (workarounds().use_virtualized_gl_contexts) {
10348 // If the context is virtual, the real context being guilty does not ensure
10349 // that the virtual context is guilty.
10350 if (reset_status == GL_GUILTY_CONTEXT_RESET_ARB) {
10351 reset_status = GL_UNKNOWN_CONTEXT_RESET_ARB;
10352 }
10353 } else if (reset_status == GL_UNKNOWN_CONTEXT_RESET_ARB &&
dongseong.hwange1cb2aa2015-02-11 09:33:3310354 IsRobustnessSupported()) {
oetuaho37cc50e2014-10-31 11:19:2010355 // If the reason for the call was a GL error, we can try to determine the
10356 // reset status more accurately.
10357 GLenum driver_status = glGetGraphicsResetStatusARB();
10358 if (driver_status == GL_GUILTY_CONTEXT_RESET_ARB ||
10359 driver_status == GL_INNOCENT_CONTEXT_RESET_ARB) {
10360 reset_status = driver_status;
10361 }
10362 }
10363
[email protected]c4485aad62012-12-17 10:19:0910364 // Marks this context as lost.
10365 reset_status_ = reset_status;
10366 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:0910367}
10368
[email protected]b096d032013-03-08 03:08:0110369error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:3410370 uint32 immediate_data_size,
10371 const void* cmd_data) {
[email protected]b096d032013-03-08 03:08:0110372 return error::kUnknownCommand;
10373}
10374
[email protected]840a7e462013-02-27 01:29:5110375error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:3410376 uint32 immediate_data_size,
10377 const void* cmd_data) {
10378 const gles2::cmds::WaitSyncPointCHROMIUM& c =
10379 *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
sievers173a20d2014-10-22 18:19:3210380 uint32 sync_point = c.sync_point;
[email protected]840a7e462013-02-27 01:29:5110381 if (wait_sync_point_callback_.is_null())
10382 return error::kNoError;
10383
sievers173a20d2014-10-22 18:19:3210384 return wait_sync_point_callback_.Run(sync_point) ?
[email protected]840a7e462013-02-27 01:29:5110385 error::kNoError : error::kDeferCommandUntilLater;
10386}
10387
[email protected]5dfc457b2013-12-13 11:13:0710388error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
vmiuracd108592014-09-08 14:36:3410389 uint32 immediate_data_size,
10390 const void* cmd_data) {
[email protected]5dfc457b2013-12-13 11:13:0710391 if (surface_->DeferDraws())
10392 return error::kDeferCommandUntilLater;
10393 if (!surface_->SetBackbufferAllocation(false))
10394 return error::kLostContext;
10395 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
10396 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
10397 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
10398 return error::kNoError;
10399}
10400
[email protected]882ba1e22012-03-08 19:02:5310401bool GLES2DecoderImpl::GenQueriesEXTHelper(
10402 GLsizei n, const GLuint* client_ids) {
10403 for (GLsizei ii = 0; ii < n; ++ii) {
10404 if (query_manager_->GetQuery(client_ids[ii])) {
10405 return false;
10406 }
10407 }
[email protected]4eea7e62014-04-22 21:14:4310408 query_manager_->GenQueries(n, client_ids);
[email protected]882ba1e22012-03-08 19:02:5310409 return true;
10410}
10411
10412void GLES2DecoderImpl::DeleteQueriesEXTHelper(
10413 GLsizei n, const GLuint* client_ids) {
10414 for (GLsizei ii = 0; ii < n; ++ii) {
10415 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
10416 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:1310417 ContextState::QueryMap::iterator it =
10418 state_.current_queries.find(query->target());
10419 if (it != state_.current_queries.end())
10420 state_.current_queries.erase(it);
10421
[email protected]c45f1972012-03-14 07:27:3610422 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:5310423 }
[email protected]4eea7e62014-04-22 21:14:4310424 query_manager_->RemoveQuery(client_ids[ii]);
[email protected]882ba1e22012-03-08 19:02:5310425 }
10426}
10427
revemancc241eb2014-11-11 03:30:3710428bool GLES2DecoderImpl::ProcessPendingQueries(bool did_finish) {
[email protected]22e3f552012-03-13 01:54:1910429 if (query_manager_.get() == NULL) {
10430 return false;
10431 }
revemancc241eb2014-11-11 03:30:3710432 if (!query_manager_->ProcessPendingQueries(did_finish)) {
[email protected]22e3f552012-03-13 01:54:1910433 current_decoder_error_ = error::kOutOfBounds;
10434 }
10435 return query_manager_->HavePendingQueries();
10436}
10437
[email protected]5a36dc132013-07-23 23:17:5510438// Note that if there are no pending readpixels right now,
10439// this function will call the callback immediately.
10440void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
10441 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
10442 pending_readpixel_fences_.back()->callbacks.push_back(callback);
10443 } else {
10444 callback.Run();
10445 }
10446}
10447
10448void GLES2DecoderImpl::ProcessPendingReadPixels() {
10449 while (!pending_readpixel_fences_.empty() &&
10450 pending_readpixel_fences_.front()->fence->HasCompleted()) {
10451 std::vector<base::Closure> callbacks =
10452 pending_readpixel_fences_.front()->callbacks;
10453 pending_readpixel_fences_.pop();
10454 for (size_t i = 0; i < callbacks.size(); i++) {
10455 callbacks[i].Run();
10456 }
10457 }
10458}
10459
[email protected]2b1767cf2013-03-16 09:25:0510460bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5510461 return !pending_readpixel_fences_.empty() ||
10462 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510463}
10464
10465void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5510466 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:4810467 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:0510468 return;
[email protected]b68b100752013-06-05 08:34:4810469 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510470 ProcessFinishedAsyncTransfers();
10471}
10472
vmiuracd108592014-09-08 14:36:3410473error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size,
10474 const void* cmd_data) {
10475 const gles2::cmds::BeginQueryEXT& c =
10476 *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310477 GLenum target = static_cast<GLenum>(c.target);
10478 GLuint client_id = static_cast<GLuint>(c.id);
10479 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
10480 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10481
[email protected]c45f1972012-03-14 07:27:3610482 switch (target) {
10483 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:5510484 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:3110485 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
10486 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:0010487 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:3610488 break;
[email protected]6a25ae422014-04-17 23:48:2710489 case GL_COMMANDS_COMPLETED_CHROMIUM:
10490 if (!features().chromium_sync_query) {
10491 LOCAL_SET_GL_ERROR(
10492 GL_INVALID_OPERATION, "glBeginQueryEXT",
10493 "not enabled for commands completed queries");
10494 return error::kNoError;
10495 }
10496 break;
[email protected]c45f1972012-03-14 07:27:3610497 default:
[email protected]62e155e2012-10-23 22:43:1510498 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:5110499 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:0010500 GL_INVALID_OPERATION, "glBeginQueryEXT",
10501 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:3610502 return error::kNoError;
10503 }
10504 break;
[email protected]882ba1e22012-03-08 19:02:5310505 }
10506
[email protected]8ebd46c2014-01-08 12:06:1310507 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110508 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310509 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:5310510 return error::kNoError;
10511 }
10512
10513 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:5110514 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:5310515 return error::kNoError;
10516 }
10517
10518 QueryManager::Query* query = query_manager_->GetQuery(client_id);
10519 if (!query) {
[email protected]4eea7e62014-04-22 21:14:4310520 if (!query_manager_->IsValidQuery(client_id)) {
10521 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10522 "glBeginQueryEXT",
10523 "id not made by glGenQueriesEXT");
10524 return error::kNoError;
10525 }
[email protected]c45f1972012-03-14 07:27:3610526 query = query_manager_->CreateQuery(
10527 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:5310528 }
10529
[email protected]c45f1972012-03-14 07:27:3610530 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110531 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310532 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:5310533 return error::kNoError;
10534 } else if (query->shm_id() != sync_shm_id ||
10535 query->shm_offset() != sync_shm_offset) {
10536 DLOG(ERROR) << "Shared memory used by query not the same as before";
10537 return error::kInvalidArguments;
10538 }
10539
[email protected]c45f1972012-03-14 07:27:3610540 if (!query_manager_->BeginQuery(query)) {
10541 return error::kOutOfBounds;
10542 }
[email protected]882ba1e22012-03-08 19:02:5310543
[email protected]8ebd46c2014-01-08 12:06:1310544 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:5310545 return error::kNoError;
10546}
10547
vmiuracd108592014-09-08 14:36:3410548error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size,
10549 const void* cmd_data) {
10550 const gles2::cmds::EndQueryEXT& c =
10551 *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310552 GLenum target = static_cast<GLenum>(c.target);
10553 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:1310554 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:5310555
[email protected]8ebd46c2014-01-08 12:06:1310556 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110557 LOCAL_SET_GL_ERROR(
10558 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:5310559 return error::kNoError;
10560 }
[email protected]882ba1e22012-03-08 19:02:5310561
[email protected]8ebd46c2014-01-08 12:06:1310562 QueryManager::Query* query = it->second.get();
10563 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:3610564 return error::kOutOfBounds;
10565 }
10566
[email protected]fe8d73c2013-02-16 22:37:3210567 query_manager_->ProcessPendingTransferQueries();
10568
[email protected]8ebd46c2014-01-08 12:06:1310569 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:5310570 return error::kNoError;
10571}
10572
[email protected]944b62f32012-09-27 02:20:4610573bool GLES2DecoderImpl::GenVertexArraysOESHelper(
10574 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610575 for (GLsizei ii = 0; ii < n; ++ii) {
10576 if (GetVertexAttribManager(client_ids[ii])) {
10577 return false;
10578 }
10579 }
[email protected]ab4fd7282012-10-12 16:25:5710580
[email protected]62e155e2012-10-23 22:43:1510581 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710582 // Emulated VAO
10583 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810584 CreateVertexAttribManager(client_ids[ii], 0, true);
[email protected]ab4fd7282012-10-12 16:25:5710585 }
10586 } else {
[email protected]40d90a22013-04-09 03:39:5510587 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:5710588
10589 glGenVertexArraysOES(n, service_ids.get());
10590 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810591 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
[email protected]ab4fd7282012-10-12 16:25:5710592 }
[email protected]944b62f32012-09-27 02:20:4610593 }
[email protected]ab4fd7282012-10-12 16:25:5710594
[email protected]944b62f32012-09-27 02:20:4610595 return true;
10596}
10597
10598void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
10599 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610600 for (GLsizei ii = 0; ii < n; ++ii) {
10601 VertexAttribManager* vao =
10602 GetVertexAttribManager(client_ids[ii]);
10603 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:1110604 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]242c9822014-04-15 21:36:1110605 DoBindVertexArrayOES(0);
[email protected]944b62f32012-09-27 02:20:4610606 }
10607 RemoveVertexAttribManager(client_ids[ii]);
10608 }
10609 }
10610}
10611
10612void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610613 VertexAttribManager* vao = NULL;
[email protected]944b62f32012-09-27 02:20:4610614 if (client_id != 0) {
10615 vao = GetVertexAttribManager(client_id);
10616 if (!vao) {
10617 // Unlike most Bind* methods, the spec explicitly states that VertexArray
10618 // only allows names that have been previously generated. As such, we do
10619 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:5110620 LOCAL_SET_GL_ERROR(
10621 GL_INVALID_OPERATION,
10622 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:4610623 current_decoder_error_ = error::kNoError;
10624 return;
[email protected]944b62f32012-09-27 02:20:4610625 }
[email protected]944b62f32012-09-27 02:20:4610626 } else {
[email protected]81f20a622014-04-18 01:54:5210627 vao = state_.default_vertex_attrib_manager.get();
[email protected]944b62f32012-09-27 02:20:4610628 }
10629
[email protected]ab4fd7282012-10-12 16:25:5710630 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:1110631 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:2410632 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:1510633 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710634 EmulateVertexArrayState();
10635 } else {
[email protected]da364812014-05-09 21:39:4810636 GLuint service_id = vao->service_id();
[email protected]ab4fd7282012-10-12 16:25:5710637 glBindVertexArrayOES(service_id);
10638 }
10639 }
10640}
10641
10642// Used when OES_vertex_array_object isn't natively supported
10643void GLES2DecoderImpl::EmulateVertexArrayState() {
10644 // Setup the Vertex attribute state
10645 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
[email protected]3fc38e22014-05-30 00:13:2310646 RestoreStateForAttrib(vv, true);
[email protected]ab4fd7282012-10-12 16:25:5710647 }
10648
10649 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:2110650 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:2410651 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:5710652 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
10653 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:4610654}
10655
10656bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610657 const VertexAttribManager* vao =
10658 GetVertexAttribManager(client_id);
10659 return vao && vao->IsValid() && !vao->IsDeleted();
10660}
10661
[email protected]e51bdf32011-11-23 22:21:4610662#if defined(OS_MACOSX)
10663void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
10664 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
10665 texture_id);
10666 if (it != texture_to_io_surface_map_.end()) {
10667 // Found a previous IOSurface bound to this texture; release it.
[email protected]c3a6b4a2014-06-04 09:25:5310668 IOSurfaceRef surface = it->second;
[email protected]e51bdf32011-11-23 22:21:4610669 CFRelease(surface);
10670 texture_to_io_surface_map_.erase(it);
10671 }
10672}
10673#endif
10674
10675void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
10676 GLenum target, GLsizei width, GLsizei height,
10677 GLuint io_surface_id, GLuint plane) {
10678#if defined(OS_MACOSX)
10679 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:5110680 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310681 GL_INVALID_OPERATION,
10682 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:4610683 return;
10684 }
10685
[email protected]e51bdf32011-11-23 22:21:4610686 if (target != GL_TEXTURE_RECTANGLE_ARB) {
10687 // This might be supported in the future, and if we could require
10688 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
10689 // could delete a lot of code. For now, perform strict validation so we
10690 // know what's going on.
[email protected]ab09b612013-03-11 22:11:5110691 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610692 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310693 "glTexImageIOSurface2DCHROMIUM",
10694 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:4610695 return;
10696 }
10697
[email protected]09d50362012-10-18 20:54:3710698 // Default target might be conceptually valid, but disallow it to avoid
10699 // accidents.
[email protected]c986af502013-08-14 01:04:4410700 TextureRef* texture_ref =
10701 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910702 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110703 LOCAL_SET_GL_ERROR(
10704 GL_INVALID_OPERATION,
10705 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:4610706 return;
10707 }
[email protected]e51bdf32011-11-23 22:21:4610708
10709 // Look up the new IOSurface. Note that because of asynchrony
10710 // between processes this might fail; during live resizing the
10711 // plugin process might allocate and release an IOSurface before
10712 // this process gets a chance to look it up. Hold on to any old
10713 // IOSurface in this case.
[email protected]c3a6b4a2014-06-04 09:25:5310714 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
[email protected]e51bdf32011-11-23 22:21:4610715 if (!surface) {
[email protected]ab09b612013-03-11 22:11:5110716 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310717 GL_INVALID_OPERATION,
10718 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:4610719 return;
10720 }
10721
10722 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:4910723 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:4610724
10725 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
10726 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:4910727 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:4610728
10729 CGLContextObj context =
10730 static_cast<CGLContextObj>(context_->GetHandle());
10731
[email protected]c3a6b4a2014-06-04 09:25:5310732 CGLError err = CGLTexImageIOSurface2D(
[email protected]e51bdf32011-11-23 22:21:4610733 context,
10734 target,
10735 GL_RGBA,
10736 width,
10737 height,
10738 GL_BGRA,
10739 GL_UNSIGNED_INT_8_8_8_8_REV,
10740 surface,
10741 plane);
10742
10743 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:5110744 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610745 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310746 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:4610747 return;
10748 }
10749
10750 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910751 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:4610752 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
10753
10754#else
[email protected]ab09b612013-03-11 22:11:5110755 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310756 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:4610757#endif
10758}
10759
[email protected]97dc7cbe2011-12-06 17:26:1710760static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
10761 switch (internalformat) {
10762 case GL_RGB565:
10763 return GL_RGB;
10764 case GL_RGBA4:
10765 return GL_RGBA;
10766 case GL_RGB5_A1:
10767 return GL_RGBA;
10768 case GL_RGB8_OES:
10769 return GL_RGB;
10770 case GL_RGBA8_OES:
10771 return GL_RGBA;
10772 case GL_LUMINANCE8_ALPHA8_EXT:
10773 return GL_LUMINANCE_ALPHA;
10774 case GL_LUMINANCE8_EXT:
10775 return GL_LUMINANCE;
10776 case GL_ALPHA8_EXT:
10777 return GL_ALPHA;
10778 case GL_RGBA32F_EXT:
10779 return GL_RGBA;
10780 case GL_RGB32F_EXT:
10781 return GL_RGB;
10782 case GL_ALPHA32F_EXT:
10783 return GL_ALPHA;
10784 case GL_LUMINANCE32F_EXT:
10785 return GL_LUMINANCE;
10786 case GL_LUMINANCE_ALPHA32F_EXT:
10787 return GL_LUMINANCE_ALPHA;
10788 case GL_RGBA16F_EXT:
10789 return GL_RGBA;
10790 case GL_RGB16F_EXT:
10791 return GL_RGB;
10792 case GL_ALPHA16F_EXT:
10793 return GL_ALPHA;
10794 case GL_LUMINANCE16F_EXT:
10795 return GL_LUMINANCE;
10796 case GL_LUMINANCE_ALPHA16F_EXT:
10797 return GL_LUMINANCE_ALPHA;
10798 case GL_BGRA8_EXT:
10799 return GL_BGRA_EXT;
bajones2a2ea232014-10-13 21:38:5910800 case GL_SRGB8_ALPHA8_EXT:
10801 return GL_SRGB_ALPHA_EXT;
[email protected]97dc7cbe2011-12-06 17:26:1710802 default:
10803 return GL_NONE;
10804 }
10805}
10806
[email protected]43410e92012-04-20 17:06:2810807void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:0310808 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:5410809 GLenum internal_format, GLenum dest_type) {
[email protected]1e24dc7f2014-04-14 02:40:0810810 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
10811
[email protected]370eaf12013-05-18 09:19:4910812 TextureRef* dest_texture_ref = GetTexture(dest_id);
10813 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:2810814
[email protected]370eaf12013-05-18 09:19:4910815 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110816 LOCAL_SET_GL_ERROR(
10817 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:2810818 return;
10819 }
10820
10821 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110822 LOCAL_SET_GL_ERROR(
10823 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:2810824 return;
10825 }
10826
[email protected]370eaf12013-05-18 09:19:4910827 Texture* source_texture = source_texture_ref->texture();
10828 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710829 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:2510830 (source_texture->target() != GL_TEXTURE_2D &&
[email protected]041d463f2014-04-30 05:38:3410831 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
10832 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]3ecc1052013-09-26 08:59:0010833 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10834 "glCopyTextureCHROMIUM",
10835 "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:0310836 return;
10837 }
10838
[email protected]43410e92012-04-20 17:06:2810839 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:2810840
[email protected]3e0dfd72014-02-21 06:28:4110841 gfx::GLImage* image =
10842 source_texture->GetLevelImage(source_texture->target(), 0);
10843 if (image) {
[email protected]7bffe9e12014-01-27 23:02:5510844 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:5610845 source_width = size.width();
10846 source_height = size.height();
10847 if (source_width <= 0 || source_height <= 0) {
10848 LOCAL_SET_GL_ERROR(
10849 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:5510850 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:5610851 return;
10852 }
[email protected]3ecc1052013-09-26 08:59:0010853 } else {
10854 if (!source_texture->GetLevelSize(
10855 source_texture->target(), 0, &source_width, &source_height)) {
10856 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10857 "glCopyTextureChromium",
10858 "source texture has no level 0");
10859 return;
10860 }
10861
10862 // Check that this type of texture is allowed.
10863 if (!texture_manager()->ValidForTarget(
10864 source_texture->target(), level, source_width, source_height, 1)) {
10865 LOCAL_SET_GL_ERROR(
10866 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
10867 return;
10868 }
[email protected]377976552013-05-14 23:32:5610869 }
10870
[email protected]04b5b37d2014-02-07 02:11:5110871 // Clear the source texture if necessary.
10872 if (!texture_manager()->ClearTextureLevel(
10873 this, source_texture_ref, source_texture->target(), 0)) {
10874 LOCAL_SET_GL_ERROR(
10875 GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big");
10876 return;
10877 }
10878
[email protected]a6e3d282014-08-22 22:20:4410879 GLenum source_type = 0;
10880 GLenum source_internal_format = 0;
10881 source_texture->GetLevelType(
10882 source_texture->target(), 0, &source_type, &source_internal_format);
10883
10884 // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
10885 // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
10886 // renderable on some platforms.
reveman6b0fbe42014-09-04 00:55:0310887 bool valid_dest_format = internal_format == GL_RGB ||
10888 internal_format == GL_RGBA ||
10889 internal_format == GL_BGRA_EXT;
[email protected]a6e3d282014-08-22 22:20:4410890 bool valid_source_format = source_internal_format == GL_ALPHA ||
10891 source_internal_format == GL_RGB ||
10892 source_internal_format == GL_RGBA ||
10893 source_internal_format == GL_LUMINANCE ||
10894 source_internal_format == GL_LUMINANCE_ALPHA ||
10895 source_internal_format == GL_BGRA_EXT;
10896 if (!valid_source_format || !valid_dest_format) {
10897 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10898 "glCopyTextureCHROMIUM",
10899 "invalid internal format");
10900 return;
10901 }
10902
[email protected]cf6b8f62012-05-25 21:43:3710903 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
10904 // needed because it takes 10s of milliseconds to initialize.
10905 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:5110906 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:3710907 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:2710908 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:3710909 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:5110910 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:3710911 return;
10912 }
10913
[email protected]efc87712014-07-09 00:22:4710914 GLenum dest_type_previous = dest_type;
10915 GLenum dest_internal_format = internal_format;
[email protected]02965c22013-03-09 02:40:0710916 bool dest_level_defined = dest_texture->GetLevelSize(
10917 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:2810918
[email protected]0a1e9ad2012-05-04 21:13:0310919 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:5410920 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:0710921 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:0310922 }
10923
10924 // Resize the destination texture to the dimensions of the source texture.
10925 if (!dest_level_defined || dest_width != source_width ||
10926 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:5410927 dest_internal_format != internal_format ||
10928 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:2810929 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:5110930 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:0710931 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:3810932 glTexImage2D(
[email protected]43410e92012-04-20 17:06:2810933 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:0310934 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:5110935 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:0310936 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:0210937 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:2810938 return;
[email protected]0a1e9ad2012-05-04 21:13:0310939 }
[email protected]43410e92012-04-20 17:06:2810940
10941 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910942 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:0310943 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:2510944 } else {
[email protected]02965c22013-03-09 02:40:0710945 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:4910946 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:2810947 }
10948
[email protected]00c2cf92014-03-14 00:08:3710949 ScopedModifyPixels modify(dest_texture_ref);
[email protected]91c94eb2013-10-22 10:32:5410950
revemance8fbe82014-09-05 02:19:5210951 // Try using GLImage::CopyTexImage when possible.
10952 bool unpack_premultiply_alpha_change =
10953 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
10954 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change && !level) {
10955 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
10956 if (image->CopyTexImage(GL_TEXTURE_2D))
10957 return;
10958 }
10959
10960 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
10961
[email protected]5394a4102013-04-18 05:41:3710962 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
10963 // before presenting.
10964 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
10965 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
10966 // instead of using default matrix crbug.com/226218.
10967 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
10968 0.0f, 1.0f, 0.0f, 0.0f,
10969 0.0f, 0.0f, 1.0f, 0.0f,
10970 0.0f, 0.0f, 0.0f, 1.0f};
10971 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
10972 this,
10973 source_texture->target(),
[email protected]5394a4102013-04-18 05:41:3710974 source_texture->service_id(),
[email protected]90f7d30d2014-08-13 02:51:5710975 dest_texture->service_id(),
10976 level,
10977 source_width,
10978 source_height,
[email protected]5394a4102013-04-18 05:41:3710979 unpack_flip_y_,
10980 unpack_premultiply_alpha_,
10981 unpack_unpremultiply_alpha_,
10982 default_matrix);
10983 } else {
[email protected]90f7d30d2014-08-13 02:51:5710984 copy_texture_CHROMIUM_->DoCopyTexture(this,
10985 source_texture->target(),
10986 source_texture->service_id(),
10987 source_internal_format,
10988 dest_texture->service_id(),
10989 level,
10990 internal_format,
10991 source_width,
10992 source_height,
10993 unpack_flip_y_,
10994 unpack_premultiply_alpha_,
10995 unpack_unpremultiply_alpha_);
[email protected]5394a4102013-04-18 05:41:3710996 }
[email protected]91c94eb2013-10-22 10:32:5410997
10998 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:2810999}
11000
[email protected]97dc7cbe2011-12-06 17:26:1711001static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
11002 switch (internalformat) {
11003 case GL_RGB565:
11004 return GL_UNSIGNED_SHORT_5_6_5;
11005 case GL_RGBA4:
11006 return GL_UNSIGNED_SHORT_4_4_4_4;
11007 case GL_RGB5_A1:
11008 return GL_UNSIGNED_SHORT_5_5_5_1;
11009 case GL_RGB8_OES:
11010 return GL_UNSIGNED_BYTE;
11011 case GL_RGBA8_OES:
11012 return GL_UNSIGNED_BYTE;
11013 case GL_LUMINANCE8_ALPHA8_EXT:
11014 return GL_UNSIGNED_BYTE;
11015 case GL_LUMINANCE8_EXT:
11016 return GL_UNSIGNED_BYTE;
11017 case GL_ALPHA8_EXT:
11018 return GL_UNSIGNED_BYTE;
11019 case GL_RGBA32F_EXT:
11020 return GL_FLOAT;
11021 case GL_RGB32F_EXT:
11022 return GL_FLOAT;
11023 case GL_ALPHA32F_EXT:
11024 return GL_FLOAT;
11025 case GL_LUMINANCE32F_EXT:
11026 return GL_FLOAT;
11027 case GL_LUMINANCE_ALPHA32F_EXT:
11028 return GL_FLOAT;
11029 case GL_RGBA16F_EXT:
11030 return GL_HALF_FLOAT_OES;
11031 case GL_RGB16F_EXT:
11032 return GL_HALF_FLOAT_OES;
11033 case GL_ALPHA16F_EXT:
11034 return GL_HALF_FLOAT_OES;
11035 case GL_LUMINANCE16F_EXT:
11036 return GL_HALF_FLOAT_OES;
11037 case GL_LUMINANCE_ALPHA16F_EXT:
11038 return GL_HALF_FLOAT_OES;
11039 case GL_BGRA8_EXT:
11040 return GL_UNSIGNED_BYTE;
11041 default:
11042 return GL_NONE;
11043 }
11044}
11045
11046void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4411047 GLenum target,
11048 GLint levels,
11049 GLenum internal_format,
11050 GLsizei width,
11051 GLsizei height) {
[email protected]67f929422014-05-17 15:33:1311052 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
11053 "width", width, "height", height);
[email protected]80eb6b52012-01-19 00:14:4111054 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0011055 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5111056 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4311057 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1711058 return;
11059 }
[email protected]c986af502013-08-14 01:04:4411060 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11061 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911062 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111063 LOCAL_SET_GL_ERROR(
11064 GL_INVALID_OPERATION,
11065 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1711066 return;
11067 }
[email protected]370eaf12013-05-18 09:19:4911068 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0711069 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4411070 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1711071 }
[email protected]02965c22013-03-09 02:40:0711072 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5111073 LOCAL_SET_GL_ERROR(
11074 GL_INVALID_OPERATION,
11075 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1711076 return;
11077 }
[email protected]7989c9e2013-01-23 06:39:2611078
11079 GLenum format = ExtractFormatFromStorageFormat(internal_format);
11080 GLenum type = ExtractTypeFromStorageFormat(internal_format);
11081
11082 {
11083 GLsizei level_width = width;
11084 GLsizei level_height = height;
11085 uint32 estimated_size = 0;
11086 for (int ii = 0; ii < levels; ++ii) {
11087 uint32 level_size = 0;
11088 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4211089 level_width, level_height, 1, format, type, state_.unpack_alignment,
[email protected]7989c9e2013-01-23 06:39:2611090 &estimated_size, NULL, NULL) ||
11091 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5111092 LOCAL_SET_GL_ERROR(
11093 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2611094 return;
11095 }
11096 level_width = std::max(1, level_width >> 1);
11097 level_height = std::max(1, level_height >> 1);
11098 }
11099 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5111100 LOCAL_SET_GL_ERROR(
11101 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2611102 return;
11103 }
11104 }
11105
[email protected]ab09b612013-03-11 22:11:5111106 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3811107 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5111108 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1711109 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1511110 GLsizei level_width = width;
11111 GLsizei level_height = height;
11112 for (int ii = 0; ii < levels; ++ii) {
11113 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911114 texture_ref, target, ii, format,
11115 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:1511116 level_width = std::max(1, level_width >> 1);
11117 level_height = std::max(1, level_height >> 1);
11118 }
[email protected]02965c22013-03-09 02:40:0711119 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1711120 }
[email protected]97dc7cbe2011-12-06 17:26:1711121}
[email protected]e51bdf32011-11-23 22:21:4611122
[email protected]78b514b2012-05-01 21:50:5911123error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
vmiuracd108592014-09-08 14:36:3411124 uint32 immediate_data_size,
11125 const void* cmd_data) {
[email protected]baed42c2013-10-01 05:06:3511126 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5911127}
11128
11129void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3711130 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0211131 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3211132 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3711133 "mailbox[0]", static_cast<unsigned char>(data[0]));
11134
[email protected]43f253da2014-06-10 17:51:2211135 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11136 &state_, target);
11137 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
11138}
11139
11140void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
11141 GLenum target, const GLbyte* data) {
11142 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
11143 "context", logger_.GetLogPrefix(),
11144 "mailbox[0]", static_cast<unsigned char>(data[0]));
11145
11146 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
11147 target, data);
11148}
11149
11150void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
11151 TextureRef* texture_ref, GLenum target, const GLbyte* data) {
[email protected]64ba52f2014-02-15 14:22:3711152 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
[email protected]43f253da2014-06-10 17:51:2211153 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
[email protected]64ba52f2014-02-15 14:22:3711154 "mailbox that was not generated by "
11155 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0211156
[email protected]370eaf12013-05-18 09:19:4911157 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111158 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2211159 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5911160 return;
11161 }
11162
[email protected]62e65f02013-05-29 22:28:1011163 Texture* produced = texture_manager()->Produce(texture_ref);
11164 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5111165 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2211166 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
11167 return;
11168 }
11169
11170 if (produced->target() != target) {
11171 LOCAL_SET_GL_ERROR(
11172 GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
[email protected]78b514b2012-05-01 21:50:5911173 return;
11174 }
11175
sievers8b373ec52014-10-24 23:04:0611176 group_->mailbox_manager()->ProduceTexture(mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5911177}
11178
11179void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3711180 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0211181 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3211182 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3711183 "mailbox[0]", static_cast<unsigned char>(data[0]));
11184 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
11185 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
11186 "mailbox that was not generated by "
11187 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0211188
[email protected]62e65f02013-05-29 22:28:1011189 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4411190 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1111191 if (!texture_ref.get()) {
11192 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11193 "glConsumeTextureCHROMIUM",
11194 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5911195 return;
11196 }
[email protected]62e65f02013-05-29 22:28:1011197 GLuint client_id = texture_ref->client_id();
11198 if (!client_id) {
11199 LOCAL_SET_GL_ERROR(
11200 GL_INVALID_OPERATION,
11201 "glConsumeTextureCHROMIUM", "unknown texture for target");
11202 return;
11203 }
sievers8b373ec52014-10-24 23:04:0611204 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]62e65f02013-05-29 22:28:1011205 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5111206 LOCAL_SET_GL_ERROR(
11207 GL_INVALID_OPERATION,
11208 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5911209 return;
11210 }
[email protected]62e65f02013-05-29 22:28:1011211 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5111212 LOCAL_SET_GL_ERROR(
11213 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1011214 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5911215 return;
11216 }
[email protected]62e65f02013-05-29 22:28:1011217
11218 DeleteTexturesHelper(1, &client_id);
11219 texture_ref = texture_manager()->Consume(client_id, texture);
11220 glBindTexture(target, texture_ref->service_id());
11221
11222 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
11223 unit.bind_target = target;
11224 switch (target) {
11225 case GL_TEXTURE_2D:
11226 unit.bound_texture_2d = texture_ref;
11227 break;
11228 case GL_TEXTURE_CUBE_MAP:
11229 unit.bound_texture_cube_map = texture_ref;
11230 break;
11231 case GL_TEXTURE_EXTERNAL_OES:
11232 unit.bound_texture_external_oes = texture_ref;
11233 break;
11234 case GL_TEXTURE_RECTANGLE_ARB:
11235 unit.bound_texture_rectangle_arb = texture_ref;
11236 break;
11237 default:
11238 NOTREACHED(); // Validation should prevent us getting here.
11239 break;
11240 }
[email protected]78b514b2012-05-01 21:50:5911241}
11242
[email protected]43f253da2014-06-10 17:51:2211243error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
11244 uint32_t immediate_data_size,
vmiuracd108592014-09-08 14:36:3411245 const void* cmd_data) {
11246 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c =
11247 *static_cast<
11248 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>(
11249 cmd_data);
[email protected]43f253da2014-06-10 17:51:2211250 GLenum target = static_cast<GLenum>(c.target);
11251 uint32_t data_size;
11252 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
11253 return error::kOutOfBounds;
11254 }
11255 if (data_size > immediate_data_size) {
11256 return error::kOutOfBounds;
11257 }
11258 const GLbyte* mailbox =
11259 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
11260 if (!validators_->texture_bind_target.IsValid(target)) {
11261 LOCAL_SET_GL_ERROR_INVALID_ENUM(
11262 "glCreateAndConsumeTextureCHROMIUM", target, "target");
11263 return error::kNoError;
11264 }
11265 if (mailbox == NULL) {
11266 return error::kOutOfBounds;
11267 }
11268 uint32_t client_id = c.client_id;
11269 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
11270 return error::kNoError;
11271}
11272
11273void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
11274 const GLbyte* data, GLuint client_id) {
11275 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
11276 "context", logger_.GetLogPrefix(),
11277 "mailbox[0]", static_cast<unsigned char>(data[0]));
11278 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
11279 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
11280 "passed a mailbox that was not "
11281 "generated by GenMailboxCHROMIUM.";
11282
11283 TextureRef* texture_ref = GetTexture(client_id);
11284 if (texture_ref) {
11285 LOCAL_SET_GL_ERROR(
11286 GL_INVALID_OPERATION,
11287 "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
11288 return;
11289 }
sievers8b373ec52014-10-24 23:04:0611290 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]43f253da2014-06-10 17:51:2211291 if (!texture) {
11292 LOCAL_SET_GL_ERROR(
11293 GL_INVALID_OPERATION,
11294 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
11295 return;
11296 }
11297 if (texture->target() != target) {
11298 LOCAL_SET_GL_ERROR(
11299 GL_INVALID_OPERATION,
11300 "glCreateAndConsumeTextureCHROMIUM", "invalid target");
11301 return;
11302 }
11303
[email protected]43f253da2014-06-10 17:51:2211304 texture_ref = texture_manager()->Consume(client_id, texture);
11305}
11306
orglofchcad5a6742014-11-07 19:51:1211307bool GLES2DecoderImpl::DoIsValuebufferCHROMIUM(GLuint client_id) {
11308 const Valuebuffer* valuebuffer = GetValuebuffer(client_id);
11309 return valuebuffer && valuebuffer->IsValid();
11310}
11311
11312void GLES2DecoderImpl::DoBindValueBufferCHROMIUM(GLenum target,
11313 GLuint client_id) {
11314 Valuebuffer* valuebuffer = NULL;
11315 if (client_id != 0) {
11316 valuebuffer = GetValuebuffer(client_id);
11317 if (!valuebuffer) {
11318 if (!group_->bind_generates_resource()) {
11319 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBindValuebufferCHROMIUM",
11320 "id not generated by glBindValuebufferCHROMIUM");
11321 return;
11322 }
11323
11324 // It's a new id so make a valuebuffer for it.
11325 CreateValuebuffer(client_id);
11326 valuebuffer = GetValuebuffer(client_id);
11327 }
11328 valuebuffer->MarkAsValid();
11329 }
11330 state_.bound_valuebuffer = valuebuffer;
11331}
11332
11333void GLES2DecoderImpl::DoSubscribeValueCHROMIUM(GLenum target,
11334 GLenum subscription) {
11335 if (!CheckCurrentValuebuffer("glSubscribeValueCHROMIUM")) {
11336 return;
11337 }
11338 state_.bound_valuebuffer.get()->AddSubscription(subscription);
11339}
11340
11341void GLES2DecoderImpl::DoPopulateSubscribedValuesCHROMIUM(GLenum target) {
11342 if (!CheckCurrentValuebuffer("glPopulateSubscribedValuesCHROMIUM")) {
11343 return;
11344 }
11345 valuebuffer_manager()->UpdateValuebufferState(state_.bound_valuebuffer.get());
11346}
11347
11348void GLES2DecoderImpl::DoUniformValueBufferCHROMIUM(GLint location,
11349 GLenum target,
11350 GLenum subscription) {
11351 if (!CheckCurrentValuebufferForSubscription(
11352 subscription, "glPopulateSubscribedValuesCHROMIUM")) {
11353 return;
11354 }
11355 if (!CheckSubscriptionTarget(location, subscription,
11356 "glPopulateSubscribedValuesCHROMIUM")) {
11357 return;
11358 }
11359 const ValueState* state =
11360 state_.bound_valuebuffer.get()->GetState(subscription);
11361 if (state) {
11362 switch (subscription) {
11363 case GL_MOUSE_POSITION_CHROMIUM:
11364 DoUniform2iv(location, 1, state->int_value);
11365 break;
11366 default:
11367 NOTREACHED() << "Unhandled uniform subscription target "
11368 << subscription;
11369 break;
11370 }
11371 }
11372}
11373
[email protected]d2a0e1a2012-08-12 02:25:0111374void GLES2DecoderImpl::DoInsertEventMarkerEXT(
11375 GLsizei length, const GLchar* marker) {
11376 if (!marker) {
11377 marker = "";
11378 }
11379 debug_marker_manager_.SetMarker(
11380 length ? std::string(marker, length) : std::string(marker));
11381}
11382
11383void GLES2DecoderImpl::DoPushGroupMarkerEXT(
11384 GLsizei length, const GLchar* marker) {
11385 if (!marker) {
11386 marker = "";
11387 }
[email protected]cac16542014-01-15 17:53:5111388 std::string name = length ? std::string(marker, length) : std::string(marker);
11389 debug_marker_manager_.PushGroup(name);
dyen4bb43282015-01-08 01:09:5611390 gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_group_marker"), name,
11391 kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0111392}
11393
11394void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
11395 debug_marker_manager_.PopGroup();
dyen4bb43282015-01-08 01:09:5611396 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0111397}
11398
[email protected]09d50362012-10-18 20:54:3711399void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
11400 GLenum target, GLint image_id) {
11401 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3711402
[email protected]bc26e8d2014-01-29 00:40:3011403 if (target == GL_TEXTURE_CUBE_MAP) {
11404 LOCAL_SET_GL_ERROR(
11405 GL_INVALID_ENUM,
11406 "glBindTexImage2DCHROMIUM", "invalid target");
11407 return;
11408 }
11409
[email protected]09d50362012-10-18 20:54:3711410 // Default target might be conceptually valid, but disallow it to avoid
11411 // accidents.
[email protected]c986af502013-08-14 01:04:4411412 TextureRef* texture_ref =
11413 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4911414 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111415 LOCAL_SET_GL_ERROR(
11416 GL_INVALID_OPERATION,
11417 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3711418 return;
11419 }
11420
11421 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
11422 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5111423 LOCAL_SET_GL_ERROR(
11424 GL_INVALID_OPERATION,
11425 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3711426 return;
11427 }
11428
[email protected]b8160812013-04-09 00:41:0411429 {
11430 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3011431 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2611432 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0411433 LOCAL_SET_GL_ERROR(
11434 GL_INVALID_OPERATION,
11435 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
11436 return;
11437 }
[email protected]09d50362012-10-18 20:54:3711438 }
11439
11440 gfx::Size size = gl_image->GetSize();
11441 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911442 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3711443 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4911444 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3711445}
11446
11447void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
11448 GLenum target, GLint image_id) {
11449 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3711450
11451 // Default target might be conceptually valid, but disallow it to avoid
11452 // accidents.
[email protected]c986af502013-08-14 01:04:4411453 TextureRef* texture_ref =
11454 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4911455 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111456 LOCAL_SET_GL_ERROR(
11457 GL_INVALID_OPERATION,
11458 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3711459 return;
11460 }
11461
11462 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
11463 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5111464 LOCAL_SET_GL_ERROR(
11465 GL_INVALID_OPERATION,
11466 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3711467 return;
11468 }
11469
11470 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4911471 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3711472 return;
11473
[email protected]b8160812013-04-09 00:41:0411474 {
11475 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3011476 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2611477 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0411478 }
[email protected]09d50362012-10-18 20:54:3711479
11480 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911481 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3711482 GL_RGBA, GL_UNSIGNED_BYTE, false);
11483}
[email protected]d2a0e1a2012-08-12 02:25:0111484
[email protected]94307712012-11-16 23:26:1111485error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
vmiuracd108592014-09-08 14:36:3411486 uint32 immediate_data_size,
11487 const void* cmd_data) {
11488 const gles2::cmds::TraceBeginCHROMIUM& c =
11489 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
dyencb86f2f2014-12-09 18:35:4111490 Bucket* category_bucket = GetBucket(c.category_bucket_id);
11491 Bucket* name_bucket = GetBucket(c.name_bucket_id);
11492 if (!category_bucket || category_bucket->size() == 0 ||
11493 !name_bucket || name_bucket->size() == 0) {
[email protected]94307712012-11-16 23:26:1111494 return error::kInvalidArguments;
11495 }
dyencb86f2f2014-12-09 18:35:4111496
11497 std::string category_name;
11498 std::string trace_name;
11499 if (!category_bucket->GetAsString(&category_name) ||
11500 !name_bucket->GetAsString(&trace_name)) {
[email protected]94307712012-11-16 23:26:1111501 return error::kInvalidArguments;
11502 }
dyencb86f2f2014-12-09 18:35:4111503
dyencb86f2f2014-12-09 18:35:4111504 if (!gpu_tracer_->Begin(category_name, trace_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5111505 LOCAL_SET_GL_ERROR(
11506 GL_INVALID_OPERATION,
11507 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1411508 return error::kNoError;
11509 }
[email protected]94307712012-11-16 23:26:1111510 return error::kNoError;
11511}
11512
11513void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
dyen4bb43282015-01-08 01:09:5611514 if (!gpu_tracer_->End(kTraceCHROMIUM)) {
11515 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11516 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1111517 return;
11518 }
[email protected]94307712012-11-16 23:26:1111519}
11520
[email protected]2f143d482013-03-14 18:04:4911521void GLES2DecoderImpl::DoDrawBuffersEXT(
11522 GLsizei count, const GLenum* bufs) {
11523 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
11524 LOCAL_SET_GL_ERROR(
11525 GL_INVALID_VALUE,
11526 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
11527 return;
11528 }
11529
11530 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
11531 if (framebuffer) {
11532 for (GLsizei i = 0; i < count; ++i) {
11533 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
11534 bufs[i] != GL_NONE) {
11535 LOCAL_SET_GL_ERROR(
11536 GL_INVALID_OPERATION,
11537 "glDrawBuffersEXT",
11538 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
11539 return;
11540 }
11541 }
11542 glDrawBuffersARB(count, bufs);
11543 framebuffer->SetDrawBuffers(count, bufs);
11544 } else { // backbuffer
11545 if (count > 1 ||
11546 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
11547 LOCAL_SET_GL_ERROR(
11548 GL_INVALID_OPERATION,
11549 "glDrawBuffersEXT",
11550 "more than one buffer or bufs not GL_NONE or GL_BACK");
11551 return;
11552 }
11553 GLenum mapped_buf = bufs[0];
11554 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
11555 bufs[0] == GL_BACK) {
11556 mapped_buf = GL_COLOR_ATTACHMENT0;
11557 }
11558 glDrawBuffersARB(count, &mapped_buf);
11559 group_->set_draw_buffer(bufs[0]);
11560 }
11561}
11562
[email protected]a6a09f852014-05-23 13:05:0311563void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
11564 group_->LoseContexts(other);
11565 reset_status_ = current;
11566 current_decoder_error_ = error::kLostContext;
11567}
11568
kkinnunen337d59632014-08-26 10:19:5711569void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
11570 const GLfloat* matrix) {
11571 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
11572 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
11573 if (!features().chromium_path_rendering) {
11574 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11575 "glMatrixLoadfCHROMIUM",
11576 "function not available");
11577 return;
11578 }
11579
11580 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
11581 ? state_.projection_matrix
11582 : state_.modelview_matrix;
11583 memcpy(target_matrix, matrix, sizeof(GLfloat) * 16);
11584 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
11585 // since the values of the _NV and _CHROMIUM tokens match.
11586 glMatrixLoadfEXT(matrix_mode, matrix);
11587}
11588
11589void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
11590 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
11591 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
11592
11593 if (!features().chromium_path_rendering) {
11594 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11595 "glMatrixLoadIdentityCHROMIUM",
11596 "function not available");
11597 return;
11598 }
11599
11600 static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
11601 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
11602 0.0f, 0.0f, 0.0f, 1.0f};
11603
11604 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
11605 ? state_.projection_matrix
11606 : state_.modelview_matrix;
11607 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
11608 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
11609 // since the values of the _NV and _CHROMIUM tokens match.
11610 glMatrixLoadIdentityEXT(matrix_mode);
11611}
11612
[email protected]32145a92012-12-17 09:01:5911613bool GLES2DecoderImpl::ValidateAsyncTransfer(
11614 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4711615 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5911616 GLenum target,
11617 GLint level,
11618 const void * data) {
11619 // We only support async uploads to 2D textures for now.
11620 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5111621 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5911622 return false;
11623 }
11624 // We only support uploads to level zero for now.
11625 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5111626 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5911627 return false;
11628 }
11629 // A transfer buffer must be bound, even for asyncTexImage2D.
11630 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5111631 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5911632 return false;
11633 }
11634 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4711635 if (!texture_ref ||
11636 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5111637 LOCAL_SET_GL_ERROR(
11638 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911639 function_name, "transfer already in progress");
11640 return false;
11641 }
11642 return true;
11643}
11644
[email protected]e3c4a9ab2014-03-31 09:07:0211645base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
11646 uint32 async_upload_token,
11647 uint32 sync_data_shm_id,
11648 uint32 sync_data_shm_offset) {
11649 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
Daniel Cheng3d7ce9f2014-08-26 00:26:2511650 if (!buffer.get() ||
11651 !buffer->GetDataAddress(sync_data_shm_offset, sizeof(AsyncUploadSync)))
[email protected]e3c4a9ab2014-03-31 09:07:0211652 return base::Closure();
11653
11654 AsyncMemoryParams mem_params(buffer,
11655 sync_data_shm_offset,
11656 sizeof(AsyncUploadSync));
11657
11658 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
11659 new AsyncUploadTokenCompletionObserver(async_upload_token));
11660
11661 return base::Bind(
11662 &AsyncPixelTransferManager::AsyncNotifyCompletion,
11663 base::Unretained(GetAsyncPixelTransferManager()),
11664 mem_params,
11665 observer);
11666}
11667
[email protected]69023942012-11-30 19:57:1611668error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411669 uint32 immediate_data_size,
11670 const void* cmd_data) {
11671 const gles2::cmds::AsyncTexImage2DCHROMIUM& c =
11672 *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611673 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611674 GLenum target = static_cast<GLenum>(c.target);
11675 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4411676 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1611677 GLsizei width = static_cast<GLsizei>(c.width);
11678 GLsizei height = static_cast<GLsizei>(c.height);
11679 GLint border = static_cast<GLint>(c.border);
11680 GLenum format = static_cast<GLenum>(c.format);
11681 GLenum type = static_cast<GLenum>(c.type);
11682 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
11683 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
11684 uint32 pixels_size;
[email protected]e3c4a9ab2014-03-31 09:07:0211685 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11686 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11687 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11688
11689 base::ScopedClosureRunner scoped_completion_callback;
11690 if (async_upload_token) {
11691 base::Closure completion_closure =
11692 AsyncUploadTokenCompletionClosure(async_upload_token,
11693 sync_data_shm_id,
11694 sync_data_shm_offset);
11695 if (completion_closure.is_null())
11696 return error::kInvalidArguments;
11697
11698 scoped_completion_callback.Reset(completion_closure);
11699 }
[email protected]32145a92012-12-17 09:01:5911700
11701 // TODO(epenner): Move this and copies of this memory validation
11702 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1611703 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4211704 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
11705 NULL, NULL)) {
[email protected]69023942012-11-30 19:57:1611706 return error::kOutOfBounds;
11707 }
11708 const void* pixels = NULL;
11709 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
11710 pixels = GetSharedMemoryAs<const void*>(
11711 pixels_shm_id, pixels_shm_offset, pixels_size);
11712 if (!pixels) {
11713 return error::kOutOfBounds;
11714 }
11715 }
11716
[email protected]c986af502013-08-14 01:04:4411717 TextureManager::DoTextImage2DArguments args = {
11718 target, level, internal_format, width, height, border, format, type,
11719 pixels, pixels_size};
11720 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5911721 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4411722 if (!texture_manager()->ValidateTexImage2D(
11723 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5911724 return error::kNoError;
11725 }
11726
11727 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4911728 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911729 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711730 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911731 return error::kNoError;
11732
11733 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0711734 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5111735 LOCAL_SET_GL_ERROR(
11736 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911737 "glAsyncTexImage2DCHROMIUM", "already defined");
11738 return error::kNoError;
11739 }
11740
[email protected]7989c9e2013-01-23 06:39:2611741 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5111742 LOCAL_SET_GL_ERROR(
11743 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2611744 return error::kNoError;
11745 }
11746
[email protected]5b3a8e02013-03-13 05:36:4411747 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3811748 AsyncTexImage2DParams tex_params = {
11749 target, level, static_cast<GLenum>(internal_format),
11750 width, height, border, format, type};
[email protected]c8021e02014-03-27 06:10:1211751 AsyncMemoryParams mem_params(
11752 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
[email protected]32145a92012-12-17 09:01:5911753
[email protected]5b3a8e02013-03-13 05:36:4411754 // Set up the async state if needed, and make the texture
11755 // immutable so the async state stays valid. The level info
11756 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1811757 AsyncPixelTransferDelegate* delegate =
11758 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
11759 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4411760 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5911761
[email protected]896425e2013-06-12 17:27:1811762 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4411763 tex_params,
11764 mem_params,
11765 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4911766 // The callback is only invoked if the transfer delegate still
11767 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4411768 // ownership that both of these pointers are valid.
11769 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4911770 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4411771 tex_params));
[email protected]f598f422012-12-07 08:30:0311772 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611773}
11774
11775error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411776 uint32 immediate_data_size,
11777 const void* cmd_data) {
11778 const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c =
11779 *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611780 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611781 GLenum target = static_cast<GLenum>(c.target);
11782 GLint level = static_cast<GLint>(c.level);
11783 GLint xoffset = static_cast<GLint>(c.xoffset);
11784 GLint yoffset = static_cast<GLint>(c.yoffset);
11785 GLsizei width = static_cast<GLsizei>(c.width);
11786 GLsizei height = static_cast<GLsizei>(c.height);
11787 GLenum format = static_cast<GLenum>(c.format);
11788 GLenum type = static_cast<GLenum>(c.type);
[email protected]e3c4a9ab2014-03-31 09:07:0211789 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11790 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11791 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11792
11793 base::ScopedClosureRunner scoped_completion_callback;
11794 if (async_upload_token) {
11795 base::Closure completion_closure =
11796 AsyncUploadTokenCompletionClosure(async_upload_token,
11797 sync_data_shm_id,
11798 sync_data_shm_offset);
11799 if (completion_closure.is_null())
11800 return error::kInvalidArguments;
11801
11802 scoped_completion_callback.Reset(completion_closure);
11803 }
[email protected]32145a92012-12-17 09:01:5911804
11805 // TODO(epenner): Move this and copies of this memory validation
11806 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1611807 uint32 data_size;
11808 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4211809 width, height, 1, format, type, state_.unpack_alignment, &data_size,
[email protected]69023942012-11-30 19:57:1611810 NULL, NULL)) {
11811 return error::kOutOfBounds;
11812 }
11813 const void* pixels = GetSharedMemoryAs<const void*>(
11814 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5911815
11816 // All the normal glTexSubImage2D validation.
11817 error::Error error = error::kNoError;
11818 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
11819 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
11820 return error;
[email protected]69023942012-11-30 19:57:1611821 }
11822
[email protected]32145a92012-12-17 09:01:5911823 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4411824 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11825 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911826 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911827 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711828 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911829 return error::kNoError;
11830
11831 // Guarantee async textures are always 'cleared' as follows:
11832 // - AsyncTexImage2D can not redefine an existing texture
11833 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
11834 // - AsyncTexSubImage2D clears synchronously if not already cleared.
11835 // - Textures become immutable after an async call.
11836 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0711837 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4911838 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
11839 target, level)) {
[email protected]ab09b612013-03-11 22:11:5111840 LOCAL_SET_GL_ERROR(
11841 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2511842 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5911843 return error::kNoError;
11844 }
11845 }
11846
[email protected]5b3a8e02013-03-13 05:36:4411847 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0311848 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5911849 width, height, format, type};
[email protected]c8021e02014-03-27 06:10:1211850 AsyncMemoryParams mem_params(
11851 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
[email protected]896425e2013-06-12 17:27:1811852 AsyncPixelTransferDelegate* delegate =
11853 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11854 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4411855 // TODO(epenner): We may want to enforce exclusive use
11856 // of async APIs in which case this should become an error,
11857 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0311858 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4411859 0, 0, 0, 0, 0, 0};
11860 texture->GetLevelSize(target, level, &define_params.width,
11861 &define_params.height);
11862 texture->GetLevelType(target, level, &define_params.type,
11863 &define_params.internal_format);
11864 // Set up the async state if needed, and make the texture
11865 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1811866 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4711867 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4411868 texture->SetImmutable(true);
11869 }
11870
[email protected]896425e2013-06-12 17:27:1811871 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5911872 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611873}
11874
[email protected]a00c1f742013-03-05 17:02:1611875error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411876 uint32 immediate_data_size,
11877 const void* cmd_data) {
11878 const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c =
11879 *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]a00c1f742013-03-05 17:02:1611880 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11881 GLenum target = static_cast<GLenum>(c.target);
11882
11883 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5111884 LOCAL_SET_GL_ERROR(
11885 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1611886 return error::kNoError;
11887 }
[email protected]c986af502013-08-14 01:04:4411888 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11889 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911890 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111891 LOCAL_SET_GL_ERROR(
11892 GL_INVALID_OPERATION,
11893 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1611894 return error::kNoError;
11895 }
[email protected]896425e2013-06-12 17:27:1811896 AsyncPixelTransferDelegate* delegate =
11897 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11898 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4911899 LOCAL_SET_GL_ERROR(
11900 GL_INVALID_OPERATION,
11901 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
11902 return error::kNoError;
11903 }
[email protected]896425e2013-06-12 17:27:1811904 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0911905 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1611906 return error::kNoError;
11907}
11908
[email protected]e3c4a9ab2014-03-31 09:07:0211909error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411910 uint32 immediate_data_size,
11911 const void* data) {
[email protected]e3c4a9ab2014-03-31 09:07:0211912 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11913
11914 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
11915 ProcessFinishedAsyncTransfers();
11916 return error::kNoError;
11917}
11918
zmo8fab00c2015-02-07 02:45:0511919error::Error GLES2DecoderImpl::HandleUniformBlockBinding(
11920 uint32_t immediate_data_size, const void* cmd_data) {
11921 if (!unsafe_es3_apis_enabled())
11922 return error::kUnknownCommand;
11923 const gles2::cmds::UniformBlockBinding& c =
11924 *static_cast<const gles2::cmds::UniformBlockBinding*>(cmd_data);
11925 GLuint client_id = c.program;
11926 GLuint index = static_cast<GLuint>(c.index);
11927 GLuint binding = static_cast<GLuint>(c.binding);
11928 Program* program = GetProgramInfoNotShader(
11929 client_id, "glUniformBlockBinding");
11930 if (!program) {
11931 return error::kNoError;
11932 }
11933 GLuint service_id = program->service_id();
11934 glUniformBlockBinding(service_id, index, binding);
11935 return error::kNoError;
11936}
11937
[email protected]91c94eb2013-10-22 10:32:5411938void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
11939 TextureRef* texture_ref) {
11940 Texture* texture = texture_ref->texture();
11941 DoDidUseTexImageIfNeeded(texture, texture->target());
11942}
11943
oetuaho37cc50e2014-10-31 11:19:2011944void GLES2DecoderImpl::OnContextLostError() {
11945 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
11946}
11947
[email protected]828a3932014-04-02 14:43:1311948void GLES2DecoderImpl::OnOutOfMemoryError() {
11949 if (lose_context_when_out_of_memory_) {
11950 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]828a3932014-04-02 14:43:1311951 }
11952}
11953
[email protected]96449d2c2009-11-25 00:01:3211954// Include the auto-generated part of this file. We split this because it means
11955// we can easily edit the non-auto generated parts right here in this file
11956// instead of having to edit some template or the code generator.
11957#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
11958
11959} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2511960} // namespace gpu