blob: aefe9794feaa7edabbbcb6a5f045216c9023c838 [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_;
[email protected]87fb6ab2012-06-13 22:28:041828 scoped_refptr<ShaderTranslator> vertex_translator_;
1829 scoped_refptr<ShaderTranslator> 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]65dfc602012-07-23 20:39:395845 ShaderTranslator* vertex_translator = NULL;
5846 ShaderTranslator* fragment_translator = NULL;
5847 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115848 vertex_translator = vertex_translator_.get();
5849 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395850 }
[email protected]df37b9932013-03-08 05:21:425851 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115852 vertex_translator,
5853 fragment_translator,
[email protected]008401532014-02-07 00:10:505854 workarounds().count_all_in_varyings_packing ?
5855 Program::kCountAll : Program::kCountOnlyStaticallyUsed,
[email protected]7cd76fd2013-06-02 21:11:115856 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425857 if (program == state_.current_program.get()) {
[email protected]b05955552014-02-06 18:41:185858 if (workarounds().use_current_program_after_successful_link)
[email protected]df37b9932013-03-08 05:21:425859 glUseProgram(program->service_id());
[email protected]b05955552014-02-06 18:41:185860 if (workarounds().clear_uniforms_before_first_program_use)
5861 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545862 }
5863 }
vmiura8266ca72014-09-09 21:37:005864
5865 // LinkProgram can be very slow. Exit command processing to allow for
5866 // context preemption and GPU watchdog checks.
5867 ExitCommandProcessingEarly();
[email protected]07f54fcc2009-12-22 02:46:305868};
5869
zmobcb3fdd62014-12-11 00:49:035870void GLES2DecoderImpl::DoSamplerParameterfv(
5871 GLuint sampler, GLenum pname, const GLfloat* params) {
5872 DCHECK(params);
5873 glSamplerParameterf(sampler, pname, params[0]);
5874}
5875
5876void GLES2DecoderImpl::DoSamplerParameteriv(
5877 GLuint sampler, GLenum pname, const GLint* params) {
5878 DCHECK(params);
5879 glSamplerParameteri(sampler, pname, params[0]);
5880}
5881
[email protected]3916c97e2010-02-25 03:20:505882void GLES2DecoderImpl::DoTexParameterf(
5883 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445884 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5885 &state_, target);
[email protected]02965c22013-03-09 02:40:075886 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515887 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245888 return;
[email protected]07f54fcc2009-12-22 02:46:305889 }
[email protected]cbb22e42011-05-12 23:36:245890
[email protected]737191ee72014-03-09 08:02:425891 texture_manager()->SetParameterf(
5892 "glTexParameterf", GetErrorState(), texture, pname, param);
[email protected]07f54fcc2009-12-22 02:46:305893}
5894
[email protected]3916c97e2010-02-25 03:20:505895void GLES2DecoderImpl::DoTexParameteri(
5896 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445897 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5898 &state_, target);
[email protected]02965c22013-03-09 02:40:075899 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515900 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245901 return;
[email protected]3916c97e2010-02-25 03:20:505902 }
[email protected]cbb22e42011-05-12 23:36:245903
[email protected]737191ee72014-03-09 08:02:425904 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505905 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505906}
5907
5908void GLES2DecoderImpl::DoTexParameterfv(
5909 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445910 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5911 &state_, target);
[email protected]02965c22013-03-09 02:40:075912 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515913 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245914 return;
[email protected]3916c97e2010-02-25 03:20:505915 }
[email protected]cbb22e42011-05-12 23:36:245916
[email protected]737191ee72014-03-09 08:02:425917 texture_manager()->SetParameterf(
5918 "glTexParameterfv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505919}
5920
5921void GLES2DecoderImpl::DoTexParameteriv(
5922 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445923 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5924 &state_, target);
[email protected]02965c22013-03-09 02:40:075925 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515926 LOCAL_SET_GL_ERROR(
5927 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245928 return;
[email protected]3916c97e2010-02-25 03:20:505929 }
[email protected]cbb22e42011-05-12 23:36:245930
[email protected]737191ee72014-03-09 08:02:425931 texture_manager()->SetParameteri(
[email protected]d3eba342013-04-18 21:11:505932 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505933}
5934
orglofchcad5a6742014-11-07 19:51:125935bool GLES2DecoderImpl::CheckCurrentValuebuffer(const char* function_name) {
5936 if (!state_.bound_valuebuffer.get()) {
5937 // There is no valuebuffer bound
5938 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5939 "no valuebuffer in use");
5940 return false;
5941 }
5942 return true;
5943}
5944
5945bool GLES2DecoderImpl::CheckCurrentValuebufferForSubscription(
5946 GLenum subscription,
5947 const char* function_name) {
5948 if (!CheckCurrentValuebuffer(function_name)) {
5949 return false;
5950 }
5951 if (!state_.bound_valuebuffer.get()->IsSubscribed(subscription)) {
5952 // The valuebuffer is not subscribed to the target
5953 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5954 "valuebuffer is not subscribed");
5955 return false;
5956 }
5957 return true;
5958}
5959
5960bool GLES2DecoderImpl::CheckSubscriptionTarget(GLint location,
5961 GLenum subscription,
5962 const char* function_name) {
5963 if (!CheckCurrentProgramForUniform(location, function_name)) {
5964 return false;
5965 }
5966 GLint real_location = -1;
5967 GLint array_index = -1;
5968 const Program::UniformInfo* info =
5969 state_.current_program->GetUniformInfoByFakeLocation(
5970 location, &real_location, &array_index);
5971 if (!info) {
5972 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "unknown location");
5973 return false;
5974 }
5975 if ((ValuebufferManager::ApiTypeForSubscriptionTarget(subscription) &
5976 info->accepts_api_type) == 0) {
5977 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
5978 "wrong type for subscription");
5979 return false;
5980 }
5981 return true;
5982}
5983
[email protected]939e7362010-05-13 20:49:105984bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115985 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435986 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515987 LOCAL_SET_GL_ERROR(
5988 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435989 return false;
[email protected]939e7362010-05-13 20:49:105990 }
[email protected]e259eb412012-10-13 05:47:245991 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515992 LOCAL_SET_GL_ERROR(
5993 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105994 return false;
5995 }
5996 return true;
5997}
5998
5999bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
6000 GLint location, const char* function_name) {
6001 if (!CheckCurrentProgram(function_name)) {
6002 return false;
6003 }
6004 return location != -1;
6005}
6006
zmof9a81360f2014-10-17 00:06:146007bool GLES2DecoderImpl::CheckDrawingFeedbackLoops() {
6008 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
6009 if (!framebuffer)
6010 return false;
6011 const Framebuffer::Attachment* attachment =
6012 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
6013 if (!attachment)
6014 return false;
6015
6016 DCHECK(state_.current_program.get());
6017 const Program::SamplerIndices& sampler_indices =
6018 state_.current_program->sampler_indices();
6019 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
6020 const Program::UniformInfo* uniform_info =
6021 state_.current_program->GetUniformInfo(sampler_indices[ii]);
6022 DCHECK(uniform_info);
6023 if (uniform_info->type != GL_SAMPLER_2D)
6024 continue;
6025 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6026 GLuint texture_unit_index = uniform_info->texture_units[jj];
6027 if (texture_unit_index >= state_.texture_units.size())
6028 continue;
6029 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
6030 TextureRef* texture_ref =
6031 texture_unit.GetInfoForSamplerType(GL_SAMPLER_2D).get();
6032 if (attachment->IsTexture(texture_ref))
6033 return true;
6034 }
6035 }
6036 return false;
6037}
6038
orglofchcad5a6742014-11-07 19:51:126039bool GLES2DecoderImpl::CheckUniformForApiType(
6040 const Program::UniformInfo* info,
6041 const char* function_name,
6042 Program::UniformApiType api_type) {
6043 DCHECK(info);
6044 if ((api_type & info->accepts_api_type) == 0) {
6045 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name,
6046 "wrong uniform function for type");
6047 return false;
6048 }
6049 return true;
6050}
6051
[email protected]43c2f1f2011-03-25 18:35:366052bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]9b1f1b52014-03-12 10:40:136053 GLint fake_location,
6054 const char* function_name,
6055 Program::UniformApiType api_type,
6056 GLint* real_location,
6057 GLenum* type,
6058 GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:366059 DCHECK(type);
6060 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:126061 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:526062
[email protected]1b0a6752012-02-22 03:44:126063 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:106064 return false;
6065 }
[email protected]43c2f1f2011-03-25 18:35:366066 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:356067 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:246068 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:126069 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:366070 if (!info) {
[email protected]ab09b612013-03-11 22:11:516071 LOCAL_SET_GL_ERROR(
6072 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:106073 return false;
6074 }
orglofchcad5a6742014-11-07 19:51:126075 if (!CheckUniformForApiType(info, function_name, api_type)) {
[email protected]476ccb72012-12-06 15:52:526076 return false;
6077 }
[email protected]43c2f1f2011-03-25 18:35:366078 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:516079 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436080 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:366081 return false;
6082 }
6083 *count = std::min(info->size - array_index, *count);
6084 if (*count <= 0) {
6085 return false;
6086 }
6087 *type = info->type;
[email protected]939e7362010-05-13 20:49:106088 return true;
6089}
6090
[email protected]1b0a6752012-02-22 03:44:126091void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
6092 GLenum type = 0;
6093 GLsizei count = 1;
6094 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136095 if (!PrepForSetUniformByLocation(fake_location,
6096 "glUniform1i",
6097 Program::kUniform1i,
6098 &real_location,
6099 &type,
6100 &count)) {
[email protected]3916c97e2010-02-25 03:20:506101 return;
6102 }
[email protected]e259eb412012-10-13 05:47:246103 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026104 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:516105 LOCAL_SET_GL_ERROR(
6106 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466107 return;
6108 }
[email protected]1b0a6752012-02-22 03:44:126109 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:506110}
6111
6112void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:126113 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:366114 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126115 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136116 if (!PrepForSetUniformByLocation(fake_location,
6117 "glUniform1iv",
6118 Program::kUniform1i,
6119 &real_location,
6120 &type,
6121 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366122 return;
6123 }
[email protected]74727112012-06-13 21:18:086124 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
6125 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:246126 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:026127 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:516128 LOCAL_SET_GL_ERROR(
6129 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:466130 return;
6131 }
[email protected]43c2f1f2011-03-25 18:35:366132 }
[email protected]1b0a6752012-02-22 03:44:126133 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:506134}
6135
[email protected]939e7362010-05-13 20:49:106136void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:126137 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366138 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126139 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136140 if (!PrepForSetUniformByLocation(fake_location,
6141 "glUniform1fv",
6142 Program::kUniform1f,
6143 &real_location,
6144 &type,
6145 &count)) {
[email protected]939e7362010-05-13 20:49:106146 return;
6147 }
6148 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:556149 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:106150 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:536151 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106152 }
[email protected]1b0a6752012-02-22 03:44:126153 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106154 } else {
[email protected]1b0a6752012-02-22 03:44:126155 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106156 }
6157}
6158
6159void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:126160 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366161 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126162 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136163 if (!PrepForSetUniformByLocation(fake_location,
6164 "glUniform2fv",
6165 Program::kUniform2f,
6166 &real_location,
6167 &type,
6168 &count)) {
[email protected]939e7362010-05-13 20:49:106169 return;
6170 }
6171 if (type == GL_BOOL_VEC2) {
6172 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:556173 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106174 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536175 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106176 }
[email protected]1b0a6752012-02-22 03:44:126177 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106178 } else {
[email protected]1b0a6752012-02-22 03:44:126179 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106180 }
6181}
6182
6183void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:126184 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366185 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126186 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136187 if (!PrepForSetUniformByLocation(fake_location,
6188 "glUniform3fv",
6189 Program::kUniform3f,
6190 &real_location,
6191 &type,
6192 &count)) {
[email protected]939e7362010-05-13 20:49:106193 return;
6194 }
6195 if (type == GL_BOOL_VEC3) {
6196 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:556197 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106198 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536199 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106200 }
[email protected]1b0a6752012-02-22 03:44:126201 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106202 } else {
[email protected]1b0a6752012-02-22 03:44:126203 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106204 }
6205}
6206
6207void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:126208 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366209 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126210 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136211 if (!PrepForSetUniformByLocation(fake_location,
6212 "glUniform4fv",
6213 Program::kUniform4f,
6214 &real_location,
6215 &type,
6216 &count)) {
[email protected]939e7362010-05-13 20:49:106217 return;
6218 }
6219 if (type == GL_BOOL_VEC4) {
6220 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:556221 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:106222 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:536223 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:106224 }
[email protected]1b0a6752012-02-22 03:44:126225 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:106226 } else {
[email protected]1b0a6752012-02-22 03:44:126227 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:106228 }
6229}
6230
[email protected]43c2f1f2011-03-25 18:35:366231void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:126232 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366233 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126234 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136235 if (!PrepForSetUniformByLocation(fake_location,
6236 "glUniform2iv",
6237 Program::kUniform2i,
6238 &real_location,
6239 &type,
6240 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366241 return;
6242 }
[email protected]1b0a6752012-02-22 03:44:126243 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366244}
6245
6246void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:126247 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366248 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126249 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136250 if (!PrepForSetUniformByLocation(fake_location,
6251 "glUniform3iv",
6252 Program::kUniform3i,
6253 &real_location,
6254 &type,
6255 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366256 return;
6257 }
[email protected]1b0a6752012-02-22 03:44:126258 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366259}
6260
6261void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:126262 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:366263 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126264 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136265 if (!PrepForSetUniformByLocation(fake_location,
6266 "glUniform4iv",
6267 Program::kUniform4i,
6268 &real_location,
6269 &type,
6270 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366271 return;
6272 }
[email protected]1b0a6752012-02-22 03:44:126273 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:366274}
6275
6276void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:126277 GLint fake_location, GLsizei count, GLboolean transpose,
6278 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366279 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126280 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136281 if (!PrepForSetUniformByLocation(fake_location,
6282 "glUniformMatrix2fv",
6283 Program::kUniformMatrix2f,
6284 &real_location,
6285 &type,
6286 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366287 return;
6288 }
[email protected]1b0a6752012-02-22 03:44:126289 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366290}
6291
6292void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:126293 GLint fake_location, GLsizei count, GLboolean transpose,
6294 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366295 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126296 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136297 if (!PrepForSetUniformByLocation(fake_location,
6298 "glUniformMatrix3fv",
6299 Program::kUniformMatrix3f,
6300 &real_location,
6301 &type,
6302 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366303 return;
6304 }
[email protected]1b0a6752012-02-22 03:44:126305 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366306}
6307
6308void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:126309 GLint fake_location, GLsizei count, GLboolean transpose,
6310 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:366311 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:126312 GLint real_location = -1;
[email protected]9b1f1b52014-03-12 10:40:136313 if (!PrepForSetUniformByLocation(fake_location,
6314 "glUniformMatrix4fv",
6315 Program::kUniformMatrix4f,
6316 &real_location,
6317 &type,
6318 &count)) {
[email protected]43c2f1f2011-03-25 18:35:366319 return;
6320 }
[email protected]1b0a6752012-02-22 03:44:126321 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:366322}
6323
[email protected]df37b9932013-03-08 05:21:426324void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:036325 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:426326 Program* program = NULL;
6327 if (program_id) {
6328 program = GetProgramInfoNotShader(program_id, "glUseProgram");
6329 if (!program) {
[email protected]ae51d192010-04-27 00:48:036330 return;
6331 }
[email protected]df37b9932013-03-08 05:21:426332 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:506333 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:516334 LOCAL_SET_GL_ERROR(
6335 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:506336 return;
6337 }
[email protected]df37b9932013-03-08 05:21:426338 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:506339 }
[email protected]7cd76fd2013-06-02 21:11:116340 if (state_.current_program.get()) {
6341 program_manager()->UnuseProgram(shader_manager(),
6342 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:146343 }
[email protected]df37b9932013-03-08 05:21:426344 state_.current_program = program;
6345 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:546346 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:116347 if (state_.current_program.get()) {
6348 program_manager()->UseProgram(state_.current_program.get());
[email protected]b05955552014-02-06 18:41:186349 if (workarounds().clear_uniforms_before_first_program_use)
6350 program_manager()->ClearUniforms(program);
[email protected]ca488e12010-12-13 20:06:146351 }
[email protected]3916c97e2010-02-25 03:20:506352}
6353
[email protected]ab09b612013-03-11 22:11:516354void GLES2DecoderImpl::RenderWarning(
6355 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:326356 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016357}
6358
[email protected]ab09b612013-03-11 22:11:516359void GLES2DecoderImpl::PerformanceWarning(
6360 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:506361 logger_.LogMessage(filename, line,
6362 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:016363}
6364
[email protected]91c94eb2013-10-22 10:32:546365void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
6366 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546367 // Image is already in use if texture is attached to a framebuffer.
6368 if (texture && !texture->IsAttachedToFramebuffer()) {
6369 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6370 if (image) {
6371 ScopedGLErrorSuppressor suppressor(
6372 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
6373 GetErrorState());
6374 glBindTexture(textarget, texture->service_id());
6375 image->WillUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026376 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546377 }
6378 }
6379}
6380
6381void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
6382 Texture* texture, GLenum textarget) {
[email protected]91c94eb2013-10-22 10:32:546383 // Image is still in use if texture is attached to a framebuffer.
6384 if (texture && !texture->IsAttachedToFramebuffer()) {
6385 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6386 if (image) {
6387 ScopedGLErrorSuppressor suppressor(
6388 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6389 GetErrorState());
6390 glBindTexture(textarget, texture->service_id());
6391 image->DidUseTexImage();
[email protected]2b10c02d2014-01-29 16:43:026392 RestoreCurrentTextureBindings(&state_, textarget);
[email protected]91c94eb2013-10-22 10:32:546393 }
6394 }
6395}
6396
[email protected]e56131d22013-07-28 16:14:116397bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:116398 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:546399 if (!texture_manager()->HaveUnrenderableTextures() &&
[email protected]7bffe9e12014-01-27 23:02:556400 !texture_manager()->HaveImages()) {
[email protected]e56131d22013-07-28 16:14:116401 return true;
[email protected]ef526492010-06-02 23:12:256402 }
[email protected]e2367b42013-05-31 03:37:216403
[email protected]ef526492010-06-02 23:12:256404 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356405 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246406 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506407 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356408 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246409 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506410 DCHECK(uniform_info);
6411 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6412 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026413 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246414 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546415 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366416 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546417 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6418 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256419 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506420 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6421 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546422 textarget,
[email protected]00f893d2010-08-24 18:55:496423 texture_manager()->black_texture_id(uniform_info->type));
dongseong.hwang7d87d722015-01-14 20:02:406424 if (!texture_ref) {
6425 LOCAL_RENDER_WARNING(
6426 std::string("there is no texture bound to the unit ") +
6427 base::IntToString(texture_unit_index));
6428 } else {
6429 LOCAL_RENDER_WARNING(
6430 std::string("texture bound to texture unit ") +
6431 base::IntToString(texture_unit_index) +
6432 " is not renderable. It maybe non-power-of-2 and have"
6433 " incompatible texture filtering.");
6434 }
[email protected]91c94eb2013-10-22 10:32:546435 continue;
[email protected]3916c97e2010-02-25 03:20:506436 }
[email protected]91c94eb2013-10-22 10:32:546437
[email protected]4e7b89202014-01-28 01:44:066438 if (textarget != GL_TEXTURE_CUBE_MAP) {
6439 Texture* texture = texture_ref->texture();
6440 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6441 if (image && !texture->IsAttachedToFramebuffer()) {
6442 ScopedGLErrorSuppressor suppressor(
6443 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6444 textures_set = true;
6445 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6446 image->WillUseTexImage();
6447 continue;
6448 }
[email protected]91c94eb2013-10-22 10:32:546449 }
[email protected]3916c97e2010-02-25 03:20:506450 }
6451 // else: should this be an error?
6452 }
6453 }
[email protected]e56131d22013-07-28 16:14:116454 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506455}
6456
[email protected]91c94eb2013-10-22 10:32:546457void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116458 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356459 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116460 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506461 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356462 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246463 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506464 DCHECK(uniform_info);
6465 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6466 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026467 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246468 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116469 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546470 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496471 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506472 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496473 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116474 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6475 ? texture_unit.bound_texture_2d.get()
6476 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506477 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496478 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546479 continue;
6480 }
6481
[email protected]4e7b89202014-01-28 01:44:066482 if (texture_unit.bind_target != GL_TEXTURE_CUBE_MAP) {
6483 Texture* texture = texture_ref->texture();
6484 gfx::GLImage* image =
6485 texture->GetLevelImage(texture_unit.bind_target, 0);
6486 if (image && !texture->IsAttachedToFramebuffer()) {
6487 ScopedGLErrorSuppressor suppressor(
6488 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6489 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6490 image->DidUseTexImage();
6491 continue;
6492 }
[email protected]3916c97e2010-02-25 03:20:506493 }
6494 }
6495 }
6496 }
6497 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246498 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306499}
6500
[email protected]0d6bfdc2011-11-02 01:32:206501bool GLES2DecoderImpl::ClearUnclearedTextures() {
6502 // Only check if there are some uncleared textures.
6503 if (!texture_manager()->HaveUnsafeTextures()) {
6504 return true;
6505 }
6506
6507 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116508 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356509 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116510 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206511 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356512 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246513 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206514 DCHECK(uniform_info);
6515 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6516 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026517 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246518 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496519 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366520 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496521 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6522 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206523 return false;
6524 }
6525 }
6526 }
6527 }
6528 }
6529 }
6530 return true;
6531}
6532
[email protected]c6aef902012-02-14 03:31:426533bool GLES2DecoderImpl::IsDrawValid(
[email protected]ac6904d62014-07-30 12:00:106534 const char* function_name, GLuint max_vertex_accessed, bool instanced,
6535 GLsizei primcount) {
6536 DCHECK(instanced || primcount == 1);
6537
[email protected]689fa1c52010-06-09 18:35:036538 // NOTE: We specifically do not check current_program->IsValid() because
6539 // it could never be invalid since glUseProgram would have failed. While
6540 // glLinkProgram could later mark the program as invalid the previous
6541 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116542 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506543 // The program does not exist.
6544 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516545 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506546 return false;
6547 }
[email protected]c6aef902012-02-14 03:31:426548
zmof9a81360f2014-10-17 00:06:146549 if (CheckDrawingFeedbackLoops()) {
6550 LOCAL_SET_GL_ERROR(
6551 GL_INVALID_OPERATION, function_name,
6552 "Source and destination textures of the draw are the same.");
6553 return false;
6554 }
6555
[email protected]7cd76fd2013-06-02 21:11:116556 return state_.vertex_attrib_manager
6557 ->ValidateBindings(function_name,
6558 this,
6559 feature_info_.get(),
6560 state_.current_program.get(),
6561 max_vertex_accessed,
[email protected]ac6904d62014-07-30 12:00:106562 instanced,
[email protected]7cd76fd2013-06-02 21:11:116563 primcount);
[email protected]b1122982010-05-17 23:04:246564}
6565
[email protected]c13e1da62011-09-09 21:48:306566bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436567 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306568 DCHECK(simulated);
6569 *simulated = false;
6570
[email protected]876f6fee2010-08-02 23:10:326571 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:306572 return true;
[email protected]876f6fee2010-08-02 23:10:326573
[email protected]ac77603c72013-03-08 13:52:066574 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356575 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246576 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246577 bool attrib_0_used =
6578 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066579 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306580 return true;
[email protected]b1122982010-05-17 23:04:246581 }
6582
[email protected]b1122982010-05-17 23:04:246583 // Make a buffer with a single repeated vec4 value enough to
6584 // simulate the constant value that is supposed to be here.
6585 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306586 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476587 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306588
6589 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476590 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306591 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516592 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306593 return false;
6594 }
6595
[email protected]ab09b612013-03-11 22:11:516596 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016597 "Attribute 0 is disabled. This has signficant performance penalty");
6598
[email protected]ab09b612013-03-11 22:11:516599 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306600 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6601
[email protected]8f0b86c2f2012-04-10 05:48:286602 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6603 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496604 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306605 GLenum error = glGetError();
6606 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516607 LOCAL_SET_GL_ERROR(
6608 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306609 return false;
6610 }
[email protected]fc753442011-02-04 19:49:496611 }
[email protected]af6380962012-11-29 23:24:136612
6613 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286614 if (new_buffer ||
6615 (attrib_0_used &&
6616 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136617 (value.v[0] != attrib_0_value_.v[0] ||
6618 value.v[1] != attrib_0_value_.v[1] ||
6619 value.v[2] != attrib_0_value_.v[2] ||
6620 value.v[3] != attrib_0_value_.v[3])))) {
6621 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496622 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6623 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136624 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246625 attrib_0_size_ = size_needed;
6626 }
6627
6628 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6629
[email protected]ac77603c72013-03-08 13:52:066630 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426631 glVertexAttribDivisorANGLE(0, 0);
6632
[email protected]c13e1da62011-09-09 21:48:306633 *simulated = true;
[email protected]b1122982010-05-17 23:04:246634 return true;
[email protected]b1122982010-05-17 23:04:246635}
6636
[email protected]3fc38e22014-05-30 00:13:236637void GLES2DecoderImpl::RestoreStateForAttrib(
6638 GLuint attrib_index, bool restore_array_binding) {
[email protected]ac77603c72013-03-08 13:52:066639 const VertexAttrib* attrib =
6640 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
[email protected]3fc38e22014-05-30 00:13:236641 if (restore_array_binding) {
6642 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6643 Buffer* buffer = attrib->buffer();
6644 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
6645 glVertexAttribPointer(
6646 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6647 attrib->gl_stride(), ptr);
6648 }
[email protected]ac77603c72013-03-08 13:52:066649 if (attrib->divisor())
6650 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246651 glBindBuffer(
[email protected]3fc38e22014-05-30 00:13:236652 GL_ARRAY_BUFFER, state_.bound_array_buffer.get() ?
6653 state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:286654
[email protected]265f8992012-07-20 01:03:146655 // Never touch vertex attribute 0's state (in particular, never
6656 // disable it) when running on desktop GL because it will never be
6657 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066658 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146659 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066660 if (attrib->enabled()) {
6661 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146662 } else {
[email protected]ac77603c72013-03-08 13:52:066663 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146664 }
[email protected]43410e92012-04-20 17:06:286665 }
[email protected]b1122982010-05-17 23:04:246666}
[email protected]07f54fcc2009-12-22 02:46:306667
[email protected]8fbedc02010-11-18 18:43:406668bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436669 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426670 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406671 DCHECK(simulated);
6672 *simulated = false;
6673 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6674 return true;
6675
[email protected]e259eb412012-10-13 05:47:246676 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406677 return true;
6678 }
6679
[email protected]ab09b612013-03-11 22:11:516680 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016681 "GL_FIXED attributes have a signficant performance penalty");
6682
[email protected]8fbedc02010-11-18 18:43:406683 // NOTE: we could be smart and try to check if a buffer is used
6684 // twice in 2 different attribs, find the overlapping parts and therefore
6685 // duplicate the minimum amount of data but this whole code path is not meant
6686 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6687 // tests so we just add to the buffer attrib used.
6688
[email protected]c13e1da62011-09-09 21:48:306689 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066690 const VertexAttribManager::VertexAttribList& enabled_attribs =
6691 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6692 for (VertexAttribManager::VertexAttribList::const_iterator it =
6693 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6694 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356695 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066696 state_.current_program->GetAttribInfoByLocation(attrib->index());
6697 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6698 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426699 GLuint num_vertices = max_accessed + 1;
6700 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516701 LOCAL_SET_GL_ERROR(
6702 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426703 return false;
6704 }
[email protected]8fbedc02010-11-18 18:43:406705 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066706 attrib->CanAccess(max_accessed) &&
6707 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476708 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066709 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476710 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516711 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436712 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406713 return false;
6714 }
6715 }
6716 }
6717
[email protected]3aad1a32012-09-07 20:54:476718 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6719 uint32 size_needed = 0;
6720 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306721 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516722 LOCAL_SET_GL_ERROR(
6723 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406724 return false;
6725 }
6726
[email protected]ab09b612013-03-11 22:11:516727 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406728
6729 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306730 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406731 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306732 GLenum error = glGetError();
6733 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516734 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436735 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306736 return false;
6737 }
[email protected]8fbedc02010-11-18 18:43:406738 }
6739
6740 // Copy the elements and convert to float
6741 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066742 for (VertexAttribManager::VertexAttribList::const_iterator it =
6743 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6744 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356745 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066746 state_.current_program->GetAttribInfoByLocation(attrib->index());
6747 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426748 max_vertex_accessed);
6749 GLuint num_vertices = max_accessed + 1;
6750 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516751 LOCAL_SET_GL_ERROR(
6752 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426753 return false;
6754 }
[email protected]8fbedc02010-11-18 18:43:406755 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066756 attrib->CanAccess(max_accessed) &&
6757 attrib->type() == GL_FIXED) {
penghuang5a3210b2014-10-29 18:24:366758 int num_elements = attrib->size() * num_vertices;
6759 const int src_size = num_elements * sizeof(int32);
6760 const int dst_size = num_elements * sizeof(float);
6761 scoped_ptr<float[]> data(new float[num_elements]);
[email protected]8fbedc02010-11-18 18:43:406762 const int32* src = reinterpret_cast<const int32 *>(
penghuang5a3210b2014-10-29 18:24:366763 attrib->buffer()->GetRange(attrib->offset(), src_size));
[email protected]8fbedc02010-11-18 18:43:406764 const int32* end = src + num_elements;
6765 float* dst = data.get();
6766 while (src != end) {
6767 *dst++ = static_cast<float>(*src++) / 65536.0f;
6768 }
penghuang5a3210b2014-10-29 18:24:366769 glBufferSubData(GL_ARRAY_BUFFER, offset, dst_size, data.get());
[email protected]8fbedc02010-11-18 18:43:406770 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066771 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406772 reinterpret_cast<GLvoid*>(offset));
penghuang5a3210b2014-10-29 18:24:366773 offset += dst_size;
[email protected]8fbedc02010-11-18 18:43:406774 }
6775 }
6776 *simulated = true;
6777 return true;
6778}
6779
6780void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6781 // There's no need to call glVertexAttribPointer because we shadow all the
6782 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246783 glBindBuffer(
6784 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116785 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6786 : 0);
[email protected]8fbedc02010-11-18 18:43:406787}
6788
[email protected]ad84a3a2012-06-08 21:42:436789error::Error GLES2DecoderImpl::DoDrawArrays(
6790 const char* function_name,
6791 bool instanced,
6792 GLenum mode,
6793 GLint first,
6794 GLsizei count,
6795 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226796 error::Error error = WillAccessBoundFramebufferForDraw();
6797 if (error != error::kNoError)
6798 return error;
[email protected]38d139d2011-07-14 00:38:436799 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516800 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436801 return error::kNoError;
6802 }
6803 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516804 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436805 return error::kNoError;
6806 }
[email protected]c6aef902012-02-14 03:31:426807 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516808 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426809 return error::kNoError;
6810 }
[email protected]ad84a3a2012-06-08 21:42:436811 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436812 return error::kNoError;
6813 }
6814 // We have to check this here because the prototype for glDrawArrays
6815 // is GLint not GLsizei.
6816 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516817 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436818 return error::kNoError;
6819 }
6820
[email protected]ac6904d62014-07-30 12:00:106821 if (count == 0 || primcount == 0) {
[email protected]ab09b612013-03-11 22:11:516822 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436823 return error::kNoError;
6824 }
6825
6826 GLuint max_vertex_accessed = first + count - 1;
[email protected]ac6904d62014-07-30 12:00:106827 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206828 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516829 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206830 return error::kNoError;
6831 }
[email protected]c13e1da62011-09-09 21:48:306832 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436833 if (!SimulateAttrib0(
6834 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306835 return error::kNoError;
6836 }
[email protected]38d139d2011-07-14 00:38:436837 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436838 if (SimulateFixedAttribs(
6839 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6840 primcount)) {
[email protected]e56131d22013-07-28 16:14:116841 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436842 ApplyDirtyState();
[email protected]00c2cf92014-03-14 00:08:376843 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426844 if (!instanced) {
6845 glDrawArrays(mode, first, count);
6846 } else {
6847 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6848 }
[email protected]38d139d2011-07-14 00:38:436849 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546850 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436851 }
6852 if (simulated_fixed_attribs) {
6853 RestoreStateForSimulatedFixedAttribs();
6854 }
6855 }
6856 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:236857 // We don't have to restore attrib 0 generic data at the end of this
6858 // function even if it is simulated. This is because we will simulate
6859 // it in each draw call, and attrib 0 generic data queries use cached
6860 // values instead of passing down to the underlying driver.
6861 RestoreStateForAttrib(0, false);
[email protected]38d139d2011-07-14 00:38:436862 }
[email protected]38d139d2011-07-14 00:38:436863 }
6864 return error::kNoError;
6865}
6866
vmiuracd108592014-09-08 14:36:346867error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size,
6868 const void* cmd_data) {
6869 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:436870 return DoDrawArrays("glDrawArrays",
6871 false,
[email protected]c6aef902012-02-14 03:31:426872 static_cast<GLenum>(c.mode),
6873 static_cast<GLint>(c.first),
6874 static_cast<GLsizei>(c.count),
[email protected]ac6904d62014-07-30 12:00:106875 1);
[email protected]c6aef902012-02-14 03:31:426876}
6877
6878error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
vmiuracd108592014-09-08 14:36:346879 uint32 immediate_data_size,
6880 const void* cmd_data) {
6881 const gles2::cmds::DrawArraysInstancedANGLE& c =
6882 *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:156883 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516884 LOCAL_SET_GL_ERROR(
6885 GL_INVALID_OPERATION,
6886 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426887 return error::kNoError;
6888 }
[email protected]ad84a3a2012-06-08 21:42:436889 return DoDrawArrays("glDrawArraysIntancedANGLE",
6890 true,
[email protected]c6aef902012-02-14 03:31:426891 static_cast<GLenum>(c.mode),
6892 static_cast<GLint>(c.first),
6893 static_cast<GLsizei>(c.count),
6894 static_cast<GLsizei>(c.primcount));
6895}
6896
[email protected]ad84a3a2012-06-08 21:42:436897error::Error GLES2DecoderImpl::DoDrawElements(
6898 const char* function_name,
6899 bool instanced,
6900 GLenum mode,
6901 GLsizei count,
6902 GLenum type,
6903 int32 offset,
6904 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226905 error::Error error = WillAccessBoundFramebufferForDraw();
6906 if (error != error::kNoError)
6907 return error;
[email protected]e259eb412012-10-13 05:47:246908 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516909 LOCAL_SET_GL_ERROR(
6910 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296911 return error::kNoError;
6912 }
6913
[email protected]8eee29c2010-04-29 03:38:296914 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516915 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296916 return error::kNoError;
6917 }
6918 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516919 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296920 return error::kNoError;
6921 }
[email protected]9438b012010-06-15 22:55:056922 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516923 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296924 return error::kNoError;
6925 }
[email protected]9438b012010-06-15 22:55:056926 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516927 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296928 return error::kNoError;
6929 }
[email protected]c6aef902012-02-14 03:31:426930 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516931 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426932 return error::kNoError;
6933 }
[email protected]8eee29c2010-04-29 03:38:296934
[email protected]ad84a3a2012-06-08 21:42:436935 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276936 return error::kNoError;
6937 }
6938
[email protected]ac6904d62014-07-30 12:00:106939 if (count == 0 || primcount == 0) {
[email protected]6c788fb72010-08-26 02:16:316940 return error::kNoError;
6941 }
6942
[email protected]8eee29c2010-04-29 03:38:296943 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086944 Buffer* element_array_buffer =
6945 state_.vertex_attrib_manager->element_array_buffer();
6946
6947 if (!element_array_buffer->GetMaxValueForRange(
6948 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516949 LOCAL_SET_GL_ERROR(
6950 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296951 return error::kNoError;
6952 }
6953
[email protected]ac6904d62014-07-30 12:00:106954 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206955 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516956 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206957 return error::kNoError;
6958 }
[email protected]c13e1da62011-09-09 21:48:306959 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436960 if (!SimulateAttrib0(
6961 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306962 return error::kNoError;
6963 }
[email protected]8fbedc02010-11-18 18:43:406964 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436965 if (SimulateFixedAttribs(
6966 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6967 primcount)) {
[email protected]e56131d22013-07-28 16:14:116968 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466969 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086970 // TODO(gman): Refactor to hide these details in BufferManager or
6971 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406972 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086973 bool used_client_side_array = false;
6974 if (element_array_buffer->IsClientSideArray()) {
6975 used_client_side_array = true;
6976 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6977 indices = element_array_buffer->GetRange(offset, 0);
6978 }
6979
[email protected]00c2cf92014-03-14 00:08:376980 ScopedRenderTo do_render(framebuffer_state_.bound_draw_framebuffer.get());
[email protected]c6aef902012-02-14 03:31:426981 if (!instanced) {
6982 glDrawElements(mode, count, type, indices);
6983 } else {
6984 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6985 }
[email protected]17cfbe0e2013-03-07 01:26:086986
6987 if (used_client_side_array) {
6988 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6989 element_array_buffer->service_id());
6990 }
6991
[email protected]8fbedc02010-11-18 18:43:406992 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546993 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:406994 }
6995 if (simulated_fixed_attribs) {
6996 RestoreStateForSimulatedFixedAttribs();
6997 }
[email protected]ba3176a2009-12-16 18:19:466998 }
[email protected]b1122982010-05-17 23:04:246999 if (simulated_attrib_0) {
[email protected]3fc38e22014-05-30 00:13:237000 // We don't have to restore attrib 0 generic data at the end of this
7001 // function even if it is simulated. This is because we will simulate
7002 // it in each draw call, and attrib 0 generic data queries use cached
7003 // values instead of passing down to the underlying driver.
7004 RestoreStateForAttrib(0, false);
[email protected]b1122982010-05-17 23:04:247005 }
[email protected]96449d2c2009-11-25 00:01:327006 }
[email protected]f7a64ee2010-02-01 22:24:147007 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327008}
7009
vmiuracd108592014-09-08 14:36:347010error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size,
7011 const void* cmd_data) {
7012 const gles2::cmds::DrawElements& c =
7013 *static_cast<const gles2::cmds::DrawElements*>(cmd_data);
[email protected]ad84a3a2012-06-08 21:42:437014 return DoDrawElements("glDrawElements",
7015 false,
[email protected]c6aef902012-02-14 03:31:427016 static_cast<GLenum>(c.mode),
7017 static_cast<GLsizei>(c.count),
7018 static_cast<GLenum>(c.type),
7019 static_cast<int32>(c.index_offset),
[email protected]ac6904d62014-07-30 12:00:107020 1);
[email protected]c6aef902012-02-14 03:31:427021}
7022
7023error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
vmiuracd108592014-09-08 14:36:347024 uint32 immediate_data_size,
7025 const void* cmd_data) {
7026 const gles2::cmds::DrawElementsInstancedANGLE& c =
7027 *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157028 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517029 LOCAL_SET_GL_ERROR(
7030 GL_INVALID_OPERATION,
7031 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:427032 return error::kNoError;
7033 }
[email protected]ad84a3a2012-06-08 21:42:437034 return DoDrawElements("glDrawElementsInstancedANGLE",
7035 true,
[email protected]c6aef902012-02-14 03:31:427036 static_cast<GLenum>(c.mode),
7037 static_cast<GLsizei>(c.count),
7038 static_cast<GLenum>(c.type),
7039 static_cast<int32>(c.index_offset),
7040 static_cast<GLsizei>(c.primcount));
7041}
7042
[email protected]269200b12010-11-18 22:53:067043GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:237044 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
7045 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:077046 Buffer* buffer = GetBuffer(buffer_id);
7047 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:037048 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517049 LOCAL_SET_GL_ERROR(
7050 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:237051 } else {
[email protected]b10492f2013-03-08 05:24:077052 if (!buffer->GetMaxValueForRange(
7053 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:037054 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:517055 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:067056 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437057 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:237058 }
7059 }
7060 return max_vertex_accessed;
7061}
7062
zmo1bb3d1d2015-01-21 20:29:437063void GLES2DecoderImpl::DoShaderSource(
7064 GLuint client_id, GLsizei count, const char** data, const GLint* length) {
7065 std::string str;
7066 for (GLsizei ii = 0; ii < count; ++ii) {
dyen7b0b4ba52015-02-04 21:38:067067 if (length && length[ii] > 0)
7068 str.append(data[ii], length[ii]);
7069 else
7070 str.append(data[ii]);
zmo1bb3d1d2015-01-21 20:29:437071 }
[email protected]df37b9932013-03-08 05:21:427072 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
7073 if (!shader) {
zmo1bb3d1d2015-01-21 20:29:437074 return;
[email protected]96449d2c2009-11-25 00:01:327075 }
[email protected]45bf5152010-02-12 00:11:317076 // Note: We don't actually call glShaderSource here. We wait until
dyen7b0b4ba52015-02-04 21:38:067077 // we actually compile the shader.
zmo576a0492014-09-13 01:12:327078 shader->set_source(str);
[email protected]558847a2010-03-24 07:02:547079}
7080
zmo38923562015-01-29 20:17:397081void GLES2DecoderImpl::DoTransformFeedbackVaryings(
7082 GLuint client_program_id, GLsizei count, const char* const* varyings,
7083 GLenum buffer_mode) {
7084 Program* program = GetProgramInfoNotShader(
7085 client_program_id, "glTransformFeedbackVaryings");
7086 if (!program) {
7087 return;
7088 }
7089 glTransformFeedbackVaryings(
7090 program->service_id(), count, varyings, buffer_mode);
7091}
7092
[email protected]ae51d192010-04-27 00:48:037093void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:387094 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:427095 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
7096 if (!shader) {
[email protected]45bf5152010-02-12 00:11:317097 return;
7098 }
[email protected]f57bb282010-11-12 00:51:347099 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:187100 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:427101 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:457102 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:417103 }
[email protected]de17df392010-04-23 21:09:417104
dyenef47e29f2015-02-05 15:51:327105 shader->RequestCompile();
7106
7107 // TODO(dyen): Currently we compile immediately when glCompileShader is
7108 // requested. Eventually this should be deffered to the linker stage.
zmo576a0492014-09-13 01:12:327109 shader->DoCompile(
[email protected]b05955552014-02-06 18:41:187110 translator,
7111 feature_info_->feature_flags().angle_translated_shader_source ?
zmo576a0492014-09-13 01:12:327112 Shader::kANGLE : Shader::kGL);
vmiura8266ca72014-09-09 21:37:007113
7114 // CompileShader can be very slow. Exit command processing to allow for
7115 // context preemption and GPU watchdog checks.
7116 ExitCommandProcessingEarly();
7117}
[email protected]45bf5152010-02-12 00:11:317118
[email protected]ddd968b82010-03-02 00:44:297119void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:427120 GLuint shader_id, GLenum pname, GLint* params) {
7121 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
7122 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:297123 return;
7124 }
[email protected]8f1ccdac2010-05-19 21:01:487125 switch (pname) {
7126 case GL_SHADER_SOURCE_LENGTH:
zmo576a0492014-09-13 01:12:327127 *params = shader->source().size();
7128 if (*params)
7129 ++(*params);
[email protected]8f1ccdac2010-05-19 21:01:487130 return;
7131 case GL_COMPILE_STATUS:
zmo576a0492014-09-13 01:12:327132 *params = compile_shader_always_succeeds_ ? true : shader->valid();
[email protected]e5186162010-06-14 18:54:417133 return;
[email protected]8f1ccdac2010-05-19 21:01:487134 case GL_INFO_LOG_LENGTH:
zmo576a0492014-09-13 01:12:327135 *params = shader->log_info().size();
7136 if (*params)
7137 ++(*params);
[email protected]e5186162010-06-14 18:54:417138 return;
[email protected]d6a53e42011-10-05 00:09:367139 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
zmo576a0492014-09-13 01:12:327140 *params = shader->translated_source().size();
7141 if (*params)
7142 ++(*params);
[email protected]d6a53e42011-10-05 00:09:367143 return;
[email protected]8f1ccdac2010-05-19 21:01:487144 default:
7145 break;
[email protected]ddd968b82010-03-02 00:44:297146 }
[email protected]df37b9932013-03-08 05:21:427147 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:297148}
7149
vmiuracd108592014-09-08 14:36:347150error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size,
7151 const void* cmd_data) {
7152 const gles2::cmds::GetShaderSource& c =
7153 *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427154 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:037155 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7156 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427157 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
zmo576a0492014-09-13 01:12:327158 if (!shader || shader->source().empty()) {
[email protected]8eee29c2010-04-29 03:38:297159 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:297160 return error::kNoError;
7161 }
zmo576a0492014-09-13 01:12:327162 bucket->SetFromString(shader->source().c_str());
[email protected]ae51d192010-04-27 00:48:037163 return error::kNoError;
7164}
7165
[email protected]d6a53e42011-10-05 00:09:367166error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
7167 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:347168 const void* cmd_data) {
7169 const gles2::cmds::GetTranslatedShaderSourceANGLE& c =
7170 *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>(
7171 cmd_data);
[email protected]df37b9932013-03-08 05:21:427172 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:367173 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7174 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427175 Shader* shader = GetShaderInfoNotProgram(
[email protected]caa13ed2014-02-17 11:29:207176 shader_id, "glGetTranslatedShaderSourceANGLE");
[email protected]df37b9932013-03-08 05:21:427177 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:367178 bucket->SetSize(0);
7179 return error::kNoError;
7180 }
7181
zmo576a0492014-09-13 01:12:327182 bucket->SetFromString(shader->translated_source().c_str());
[email protected]d6a53e42011-10-05 00:09:367183 return error::kNoError;
7184}
7185
[email protected]ae51d192010-04-27 00:48:037186error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
vmiuracd108592014-09-08 14:36:347187 uint32 immediate_data_size,
7188 const void* cmd_data) {
7189 const gles2::cmds::GetProgramInfoLog& c =
7190 *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427191 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:587192 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7193 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427194 Program* program = GetProgramInfoNotShader(
7195 program_id, "glGetProgramInfoLog");
7196 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:467197 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037198 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:317199 }
[email protected]df37b9932013-03-08 05:21:427200 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:037201 return error::kNoError;
7202}
7203
7204error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
vmiuracd108592014-09-08 14:36:347205 uint32 immediate_data_size,
7206 const void* cmd_data) {
7207 const gles2::cmds::GetShaderInfoLog& c =
7208 *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:427209 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:587210 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
7211 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:427212 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
zmo576a0492014-09-13 01:12:327213 if (!shader) {
[email protected]9a14ae612011-08-08 17:51:467214 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:037215 return error::kNoError;
7216 }
zmo576a0492014-09-13 01:12:327217 bucket->SetFromString(shader->log_info().c_str());
[email protected]ae51d192010-04-27 00:48:037218 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327219}
7220
[email protected]d058bca2012-11-26 10:27:267221bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
7222 return state_.GetEnabled(cap);
7223}
7224
[email protected]1958e0e2010-04-22 05:17:157225bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:217226 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107227 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157228}
7229
7230bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357231 const Framebuffer* framebuffer =
7232 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107233 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157234}
7235
7236bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367237 // IsProgram is true for programs as soon as they are created, until they are
7238 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:357239 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:107240 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157241}
7242
7243bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:357244 const Renderbuffer* renderbuffer =
7245 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:107246 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157247}
7248
7249bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:367250 // IsShader is true for shaders as soon as they are created, until they
7251 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:357252 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:107253 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:157254}
7255
7256bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:497257 const TextureRef* texture_ref = GetTexture(client_id);
7258 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:037259}
7260
7261void GLES2DecoderImpl::DoAttachShader(
7262 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427263 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587264 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:427265 if (!program) {
[email protected]ae51d192010-04-27 00:48:037266 return;
[email protected]1958e0e2010-04-22 05:17:157267 }
[email protected]df37b9932013-03-08 05:21:427268 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
7269 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037270 return;
7271 }
[email protected]df37b9932013-03-08 05:21:427272 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517273 LOCAL_SET_GL_ERROR(
7274 GL_INVALID_OPERATION,
7275 "glAttachShader",
7276 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:317277 return;
7278 }
[email protected]df37b9932013-03-08 05:21:427279 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037280}
7281
7282void GLES2DecoderImpl::DoDetachShader(
7283 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:427284 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587285 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:427286 if (!program) {
[email protected]ae51d192010-04-27 00:48:037287 return;
7288 }
[email protected]df37b9932013-03-08 05:21:427289 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
7290 if (!shader) {
[email protected]ae51d192010-04-27 00:48:037291 return;
7292 }
[email protected]df37b9932013-03-08 05:21:427293 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:517294 LOCAL_SET_GL_ERROR(
7295 GL_INVALID_OPERATION,
7296 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:227297 return;
7298 }
[email protected]df37b9932013-03-08 05:21:427299 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:037300}
7301
7302void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:427303 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587304 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:427305 if (!program) {
[email protected]ae51d192010-04-27 00:48:037306 return;
7307 }
[email protected]df37b9932013-03-08 05:21:427308 program->Validate();
[email protected]1958e0e2010-04-22 05:17:157309}
7310
[email protected]ac77603c72013-03-08 13:52:067311void GLES2DecoderImpl::GetVertexAttribHelper(
7312 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:247313 switch (pname) {
7314 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:067315 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:247316 if (buffer && !buffer->IsDeleted()) {
7317 GLuint client_id;
7318 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
7319 *params = client_id;
7320 }
7321 break;
7322 }
7323 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:067324 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:247325 break;
7326 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:067327 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:247328 break;
7329 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:067330 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:247331 break;
7332 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:067333 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:247334 break;
7335 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:067336 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:247337 break;
[email protected]c6aef902012-02-14 03:31:427338 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:067339 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:427340 break;
[email protected]ac77603c72013-03-08 13:52:067341 default:
7342 NOTREACHED();
7343 break;
7344 }
7345}
7346
[email protected]4c6f5462014-03-05 00:26:567347void GLES2DecoderImpl::DoGetTexParameterfv(
7348 GLenum target, GLenum pname, GLfloat* params) {
7349 InitTextureMaxAnisotropyIfNeeded(target, pname);
7350 glGetTexParameterfv(target, pname, params);
7351}
7352
7353void GLES2DecoderImpl::DoGetTexParameteriv(
7354 GLenum target, GLenum pname, GLint* params) {
7355 InitTextureMaxAnisotropyIfNeeded(target, pname);
7356 glGetTexParameteriv(target, pname, params);
7357}
7358
7359void GLES2DecoderImpl::InitTextureMaxAnisotropyIfNeeded(
7360 GLenum target, GLenum pname) {
7361 if (!workarounds().init_texture_max_anisotropy)
7362 return;
7363 if (pname != GL_TEXTURE_MAX_ANISOTROPY_EXT ||
7364 !validators_->texture_parameter.IsValid(pname)) {
7365 return;
7366 }
7367
7368 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7369 &state_, target);
7370 if (!texture_ref) {
7371 LOCAL_SET_GL_ERROR(
7372 GL_INVALID_OPERATION,
7373 "glGetTexParamter{fi}v", "unknown texture for target");
7374 return;
7375 }
7376 Texture* texture = texture_ref->texture();
7377 texture->InitTextureMaxAnisotropyIfNeeded(target);
7378}
7379
[email protected]ac77603c72013-03-08 13:52:067380void GLES2DecoderImpl::DoGetVertexAttribfv(
7381 GLuint index, GLenum pname, GLfloat* params) {
7382 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7383 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517384 LOCAL_SET_GL_ERROR(
7385 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067386 return;
7387 }
7388 switch (pname) {
7389 case GL_CURRENT_VERTEX_ATTRIB: {
7390 const Vec4& value = state_.attrib_values[index];
7391 params[0] = value.v[0];
7392 params[1] = value.v[1];
7393 params[2] = value.v[2];
7394 params[3] = value.v[3];
7395 break;
7396 }
7397 default: {
7398 GLint value = 0;
7399 GetVertexAttribHelper(attrib, pname, &value);
7400 *params = static_cast<GLfloat>(value);
7401 break;
7402 }
7403 }
7404}
7405
7406void GLES2DecoderImpl::DoGetVertexAttribiv(
7407 GLuint index, GLenum pname, GLint* params) {
7408 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
7409 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:517410 LOCAL_SET_GL_ERROR(
7411 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:067412 return;
7413 }
7414 switch (pname) {
[email protected]af6380962012-11-29 23:24:137415 case GL_CURRENT_VERTEX_ATTRIB: {
7416 const Vec4& value = state_.attrib_values[index];
7417 params[0] = static_cast<GLint>(value.v[0]);
7418 params[1] = static_cast<GLint>(value.v[1]);
7419 params[2] = static_cast<GLint>(value.v[2]);
7420 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:247421 break;
[email protected]af6380962012-11-29 23:24:137422 }
[email protected]b1122982010-05-17 23:04:247423 default:
[email protected]ac77603c72013-03-08 13:52:067424 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:247425 break;
7426 }
7427}
7428
[email protected]af6380962012-11-29 23:24:137429bool GLES2DecoderImpl::SetVertexAttribValue(
7430 const char* function_name, GLuint index, const GLfloat* value) {
7431 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:517432 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:137433 return false;
[email protected]b1122982010-05-17 23:04:247434 }
[email protected]af6380962012-11-29 23:24:137435 Vec4& v = state_.attrib_values[index];
7436 v.v[0] = value[0];
7437 v.v[1] = value[1];
7438 v.v[2] = value[2];
7439 v.v[3] = value[3];
7440 return true;
7441}
7442
7443void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
7444 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
7445 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
7446 glVertexAttrib1f(index, v0);
7447 }
[email protected]b1122982010-05-17 23:04:247448}
7449
7450void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:137451 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
7452 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
7453 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:247454 }
[email protected]b1122982010-05-17 23:04:247455}
7456
7457void GLES2DecoderImpl::DoVertexAttrib3f(
7458 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:137459 GLfloat v[4] = { v0, v1, v2, 1.0f, };
7460 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
7461 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:247462 }
[email protected]b1122982010-05-17 23:04:247463}
7464
7465void GLES2DecoderImpl::DoVertexAttrib4f(
7466 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137467 GLfloat v[4] = { v0, v1, v2, v3, };
7468 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7469 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247470 }
[email protected]b1122982010-05-17 23:04:247471}
7472
7473void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137474 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7475 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7476 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247477 }
[email protected]b1122982010-05-17 23:04:247478}
7479
7480void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137481 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7482 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7483 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247484 }
[email protected]b1122982010-05-17 23:04:247485}
7486
7487void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137488 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7489 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7490 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247491 }
[email protected]b1122982010-05-17 23:04:247492}
7493
7494void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137495 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7496 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247497 }
[email protected]b1122982010-05-17 23:04:247498}
7499
zmo0c4b7cf2014-11-26 00:52:117500error::Error GLES2DecoderImpl::HandleVertexAttribIPointer(
7501 uint32 immediate_data_size,
7502 const void* cmd_data) {
7503 // TODO(zmo): Unsafe ES3 API, missing states update.
7504 if (!unsafe_es3_apis_enabled())
7505 return error::kUnknownCommand;
7506 const gles2::cmds::VertexAttribIPointer& c =
7507 *static_cast<const gles2::cmds::VertexAttribIPointer*>(cmd_data);
7508 GLuint indx = c.indx;
7509 GLint size = c.size;
7510 GLenum type = c.type;
7511 GLsizei stride = c.stride;
7512 GLsizei offset = c.offset;
7513 const void* ptr = reinterpret_cast<const void*>(offset);
7514 glVertexAttribIPointer(indx, size, type, stride, ptr);
7515 return error::kNoError;
7516}
7517
[email protected]f7a64ee2010-02-01 22:24:147518error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
vmiuracd108592014-09-08 14:36:347519 uint32 immediate_data_size,
7520 const void* cmd_data) {
7521 const gles2::cmds::VertexAttribPointer& c =
7522 *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data);
[email protected]944b62f32012-09-27 02:20:467523
[email protected]7cd76fd2013-06-02 21:11:117524 if (!state_.bound_array_buffer.get() ||
7525 state_.bound_array_buffer->IsDeleted()) {
7526 if (state_.vertex_attrib_manager.get() ==
[email protected]81f20a622014-04-18 01:54:527527 state_.default_vertex_attrib_manager.get()) {
[email protected]ab09b612013-03-11 22:11:517528 LOCAL_SET_GL_ERROR(
7529 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:467530 return error::kNoError;
7531 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:517532 LOCAL_SET_GL_ERROR(
7533 GL_INVALID_VALUE,
7534 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:467535 return error::kNoError;
7536 }
[email protected]96449d2c2009-11-25 00:01:327537 }
[email protected]8eee29c2010-04-29 03:38:297538
7539 GLuint indx = c.indx;
7540 GLint size = c.size;
7541 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327542 GLboolean normalized = static_cast<GLboolean>(c.normalized);
[email protected]8eee29c2010-04-29 03:38:297543 GLsizei stride = c.stride;
7544 GLsizei offset = c.offset;
7545 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057546 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517547 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297548 return error::kNoError;
7549 }
[email protected]9438b012010-06-15 22:55:057550 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517551 LOCAL_SET_GL_ERROR(
7552 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297553 return error::kNoError;
7554 }
7555 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517556 LOCAL_SET_GL_ERROR(
7557 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297558 return error::kNoError;
7559 }
7560 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517561 LOCAL_SET_GL_ERROR(
7562 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297563 return error::kNoError;
7564 }
7565 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517566 LOCAL_SET_GL_ERROR(
7567 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297568 return error::kNoError;
7569 }
7570 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517571 LOCAL_SET_GL_ERROR(
7572 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297573 return error::kNoError;
7574 }
7575 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317576 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]a07a23602014-08-05 11:36:127577 // component_size must be a power of two to use & as optimized modulo.
7578 DCHECK(GLES2Util::IsPOT(component_size));
7579 if (offset & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517580 LOCAL_SET_GL_ERROR(
7581 GL_INVALID_OPERATION,
7582 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317583 return error::kNoError;
7584 }
[email protected]a07a23602014-08-05 11:36:127585 if (stride & (component_size - 1)) {
[email protected]ab09b612013-03-11 22:11:517586 LOCAL_SET_GL_ERROR(
7587 GL_INVALID_OPERATION,
7588 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297589 return error::kNoError;
7590 }
[email protected]7cd76fd2013-06-02 21:11:117591 state_.vertex_attrib_manager
7592 ->SetAttribInfo(indx,
7593 state_.bound_array_buffer.get(),
7594 size,
7595 type,
7596 normalized,
7597 stride,
7598 stride != 0 ? stride : component_size * size,
7599 offset);
[email protected]8fbedc02010-11-18 18:43:407600 if (type != GL_FIXED) {
7601 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7602 }
[email protected]f7a64ee2010-02-01 22:24:147603 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327604}
7605
[email protected]43410e92012-04-20 17:06:287606void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7607 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247608 state_.viewport_x = x;
7609 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027610 state_.viewport_width = std::min(width, viewport_max_width_);
7611 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287612 glViewport(x, y, width, height);
7613}
7614
[email protected]c6aef902012-02-14 03:31:427615error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
vmiuracd108592014-09-08 14:36:347616 uint32 immediate_data_size,
7617 const void* cmd_data) {
7618 const gles2::cmds::VertexAttribDivisorANGLE& c =
7619 *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data);
[email protected]62e155e2012-10-23 22:43:157620 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517621 LOCAL_SET_GL_ERROR(
7622 GL_INVALID_OPERATION,
7623 "glVertexAttribDivisorANGLE", "function not available");
[email protected]cedee332014-05-23 07:07:537624 return error::kNoError;
[email protected]c6aef902012-02-14 03:31:427625 }
7626 GLuint index = c.index;
7627 GLuint divisor = c.divisor;
7628 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517629 LOCAL_SET_GL_ERROR(
7630 GL_INVALID_VALUE,
7631 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427632 return error::kNoError;
7633 }
7634
[email protected]e259eb412012-10-13 05:47:247635 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427636 index,
7637 divisor);
7638 glVertexAttribDivisorANGLE(index, divisor);
7639 return error::kNoError;
7640}
7641
[email protected]68586372013-12-11 01:27:597642template <typename pixel_data_type>
7643static void WriteAlphaData(
7644 void *pixels, uint32 row_count, uint32 channel_count,
7645 uint32 alpha_channel_index, uint32 unpadded_row_size,
7646 uint32 padded_row_size, pixel_data_type alpha_value) {
7647 DCHECK_GT(channel_count, 0U);
7648 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7649 uint32 unpadded_row_size_in_elements =
7650 unpadded_row_size / sizeof(pixel_data_type);
7651 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7652 uint32 padded_row_size_in_elements =
7653 padded_row_size / sizeof(pixel_data_type);
7654 pixel_data_type* dst =
7655 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7656 for (uint32 yy = 0; yy < row_count; ++yy) {
7657 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7658 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7659 *d = alpha_value;
7660 }
7661 dst += padded_row_size_in_elements;
7662 }
7663}
7664
[email protected]5a36dc132013-07-23 23:17:557665void GLES2DecoderImpl::FinishReadPixels(
7666 const cmds::ReadPixels& c,
7667 GLuint buffer) {
7668 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7669 GLsizei width = c.width;
7670 GLsizei height = c.height;
7671 GLenum format = c.format;
7672 GLenum type = c.type;
7673 typedef cmds::ReadPixels::Result Result;
7674 uint32 pixels_size;
7675 Result* result = NULL;
7676 if (c.result_shm_id != 0) {
7677 result = GetSharedMemoryAs<Result*>(
7678 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7679 if (!result) {
7680 if (buffer != 0) {
7681 glDeleteBuffersARB(1, &buffer);
7682 }
7683 return;
7684 }
7685 }
7686 GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427687 width, height, 1, format, type, state_.pack_alignment, &pixels_size,
[email protected]5a36dc132013-07-23 23:17:557688 NULL, NULL);
7689 void* pixels = GetSharedMemoryAs<void*>(
7690 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7691 if (!pixels) {
7692 if (buffer != 0) {
7693 glDeleteBuffersARB(1, &buffer);
7694 }
7695 return;
7696 }
7697
7698 if (buffer != 0) {
7699 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337700 void* data;
7701 if (features().map_buffer_range) {
7702 data = glMapBufferRange(
7703 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7704 } else {
7705 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7706 }
miub70d78592014-11-15 03:53:477707 if (!data) {
7708 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glMapBuffer",
7709 "Unable to map memory for readback.");
7710 return;
7711 }
[email protected]5a36dc132013-07-23 23:17:557712 memcpy(pixels, data, pixels_size);
7713 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7714 // have to restore the state.
7715 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7716 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7717 glDeleteBuffersARB(1, &buffer);
7718 }
7719
7720 if (result != NULL) {
7721 *result = true;
7722 }
7723
7724 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7725 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7726 if ((channels_exist & 0x0008) == 0 &&
7727 workarounds().clear_alpha_in_readpixels) {
7728 // Set the alpha to 255 because some drivers are buggy in this regard.
7729 uint32 temp_size;
7730
7731 uint32 unpadded_row_size;
7732 uint32 padded_row_size;
7733 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427734 width, 2, 1, format, type, state_.pack_alignment, &temp_size,
[email protected]5a36dc132013-07-23 23:17:557735 &unpadded_row_size, &padded_row_size)) {
7736 return;
7737 }
[email protected]68586372013-12-11 01:27:597738
7739 uint32 channel_count = 0;
7740 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557741 switch (format) {
7742 case GL_RGBA:
7743 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597744 channel_count = 4;
7745 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557746 break;
[email protected]68586372013-12-11 01:27:597747 case GL_ALPHA:
7748 channel_count = 1;
7749 alpha_channel = 0;
7750 break;
7751 }
7752
7753 if (channel_count > 0) {
7754 switch (type) {
7755 case GL_UNSIGNED_BYTE:
7756 WriteAlphaData<uint8>(
7757 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7758 padded_row_size, 0xFF);
7759 break;
7760 case GL_FLOAT:
7761 WriteAlphaData<float>(
7762 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7763 padded_row_size, 1.0f);
7764 break;
7765 case GL_HALF_FLOAT:
7766 WriteAlphaData<uint16>(
7767 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7768 padded_row_size, 0x3C00);
7769 break;
[email protected]5a36dc132013-07-23 23:17:557770 }
[email protected]5a36dc132013-07-23 23:17:557771 }
7772 }
7773}
7774
vmiuracd108592014-09-08 14:36:347775error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
7776 const void* cmd_data) {
7777 const gles2::cmds::ReadPixels& c =
7778 *static_cast<const gles2::cmds::ReadPixels*>(cmd_data);
[email protected]c959a09a2014-03-27 11:44:217779 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
[email protected]c76fe672013-12-13 23:30:227780 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7781 if (fbo_error != error::kNoError)
7782 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317783 GLint x = c.x;
7784 GLint y = c.y;
7785 GLsizei width = c.width;
7786 GLsizei height = c.height;
7787 GLenum format = c.format;
7788 GLenum type = c.type;
pkasting45796dc2014-10-17 04:18:327789 GLboolean async = static_cast<GLboolean>(c.async);
[email protected]57f223832010-03-19 01:57:567790 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517791 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567792 return error::kNoError;
7793 }
[email protected]ed9f9cd2013-02-27 21:12:357794 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187795 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347796 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427797 width, height, 1, format, type, state_.pack_alignment, &pixels_size,
[email protected]e259eb412012-10-13 05:47:247798 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187799 return error::kOutOfBounds;
7800 }
[email protected]612d2f82009-12-08 20:49:317801 void* pixels = GetSharedMemoryAs<void*>(
7802 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107803 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147804 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467805 }
[email protected]de43f082013-04-02 01:16:107806 Result* result = NULL;
7807 if (c.result_shm_id != 0) {
7808 result = GetSharedMemoryAs<Result*>(
7809 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7810 if (!result) {
7811 return error::kOutOfBounds;
7812 }
7813 }
[email protected]a51788e2010-02-24 21:54:257814
[email protected]9438b012010-06-15 22:55:057815 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517816 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297817 return error::kNoError;
7818 }
[email protected]68586372013-12-11 01:27:597819 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517820 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127821 return error::kNoError;
7822 }
[email protected]68586372013-12-11 01:27:597823 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7824 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7825 // format and type are acceptable enums but not guaranteed to be supported
7826 // for this framebuffer. Have to ask gl if they are valid.
7827 GLint preferred_format = 0;
7828 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7829 GLint preferred_type = 0;
7830 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7831 if (format != static_cast<GLenum>(preferred_format) ||
7832 type != static_cast<GLenum>(preferred_type)) {
7833 LOCAL_SET_GL_ERROR(
7834 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7835 "with the current read framebuffer");
7836 return error::kNoError;
7837 }
7838 }
[email protected]57f223832010-03-19 01:57:567839 if (width == 0 || height == 0) {
7840 return error::kNoError;
7841 }
7842
[email protected]57f223832010-03-19 01:57:567843 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307844 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567845
[email protected]3aad1a32012-09-07 20:54:477846 int32 max_x;
7847 int32 max_y;
7848 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517849 LOCAL_SET_GL_ERROR(
7850 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147851 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317852 }
[email protected]57f223832010-03-19 01:57:567853
[email protected]2ea5950d2014-07-09 18:20:347854 if (!CheckBoundReadFramebufferColorAttachment("glReadPixels")) {
7855 return error::kNoError;
7856 }
7857
[email protected]0d6bfdc2011-11-02 01:32:207858 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7859 return error::kNoError;
7860 }
7861
[email protected]caa13ed2014-02-17 11:29:207862 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixels");
[email protected]a0b78dc2011-11-11 10:43:107863
7864 ScopedResolvedFrameBufferBinder binder(this, false, true);
7865
[email protected]d37231fa2010-04-09 21:16:027866 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567867 // The user requested an out of range area. Get the results 1 line
7868 // at a time.
7869 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347870 uint32 unpadded_row_size;
7871 uint32 padded_row_size;
7872 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427873 width, 2, 1, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347874 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517875 LOCAL_SET_GL_ERROR(
7876 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567877 return error::kNoError;
7878 }
7879
7880 GLint dest_x_offset = std::max(-x, 0);
7881 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347882 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:427883 dest_x_offset, 1, 1, format, type, state_.pack_alignment,
7884 &dest_row_offset, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517885 LOCAL_SET_GL_ERROR(
7886 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567887 return error::kNoError;
7888 }
7889
7890 // Copy each row into the larger dest rect.
7891 int8* dst = static_cast<int8*>(pixels);
7892 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027893 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567894 GLint read_width = read_end_x - read_x;
7895 for (GLint yy = 0; yy < height; ++yy) {
7896 GLint ry = y + yy;
7897
7898 // Clear the row.
7899 memset(dst, 0, unpadded_row_size);
7900
7901 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027902 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567903 glReadPixels(
7904 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7905 }
7906 dst += padded_row_size;
7907 }
7908 } else {
[email protected]5a36dc132013-07-23 23:17:557909 if (async && features().use_async_readpixels) {
miu50cef602014-11-11 01:35:417910 GLuint buffer = 0;
[email protected]5a36dc132013-07-23 23:17:557911 glGenBuffersARB(1, &buffer);
7912 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
miub70d78592014-11-15 03:53:477913 // For ANGLE client version 2, GL_STREAM_READ is not available.
zmo68fcdc62014-12-05 21:51:497914 const GLenum usage_hint = feature_info_->gl_version_info().is_angle ?
7915 GL_STATIC_DRAW : GL_STREAM_READ;
miub70d78592014-11-15 03:53:477916 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, usage_hint);
[email protected]5a36dc132013-07-23 23:17:557917 GLenum error = glGetError();
7918 if (error == GL_NO_ERROR) {
7919 glReadPixels(x, y, width, height, format, type, 0);
7920 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7921 new FenceCallback()));
7922 WaitForReadPixels(base::Bind(
7923 &GLES2DecoderImpl::FinishReadPixels,
7924 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7925 <GLES2DecoderImpl>(this),
7926 c, buffer));
7927 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7928 return error::kNoError;
[email protected]77bfe7442014-03-01 02:42:597929 } else {
7930 // On error, unbind pack buffer and fall through to sync readpixels
7931 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
miu50cef602014-11-11 01:35:417932 glDeleteBuffersARB(1, &buffer);
[email protected]5a36dc132013-07-23 23:17:557933 }
7934 }
[email protected]57f223832010-03-19 01:57:567935 glReadPixels(x, y, width, height, format, type, pixels);
7936 }
[email protected]ab09b612013-03-11 22:11:517937 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257938 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107939 if (result != NULL) {
7940 *result = true;
7941 }
[email protected]5a36dc132013-07-23 23:17:557942 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257943 }
[email protected]4848b9f82011-03-10 18:37:567944
[email protected]f7a64ee2010-02-01 22:24:147945 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327946}
7947
vmiuracd108592014-09-08 14:36:347948error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size,
7949 const void* cmd_data) {
7950 const gles2::cmds::PixelStorei& c =
7951 *static_cast<const gles2::cmds::PixelStorei*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:197952 GLenum pname = c.pname;
7953 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057954 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517955 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127956 return error::kNoError;
7957 }
[email protected]222471d2011-11-30 18:06:397958 switch (pname) {
7959 case GL_PACK_ALIGNMENT:
7960 case GL_UNPACK_ALIGNMENT:
7961 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517962 LOCAL_SET_GL_ERROR(
[email protected]caa13ed2014-02-17 11:29:207963 GL_INVALID_VALUE, "glPixelStorei", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397964 return error::kNoError;
7965 }
[email protected]164d6d52012-05-05 00:55:037966 break;
[email protected]0a1e9ad2012-05-04 21:13:037967 case GL_UNPACK_FLIP_Y_CHROMIUM:
7968 unpack_flip_y_ = (param != 0);
7969 return error::kNoError;
7970 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7971 unpack_premultiply_alpha_ = (param != 0);
7972 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177973 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7974 unpack_unpremultiply_alpha_ = (param != 0);
7975 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397976 default:
7977 break;
[email protected]b9849abf2009-11-25 19:13:197978 }
7979 glPixelStorei(pname, param);
7980 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437981 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247982 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437983 break;
7984 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427985 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437986 break;
7987 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247988 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437989 break;
7990 default:
7991 // Validation should have prevented us from getting here.
7992 NOTREACHED();
7993 break;
[email protected]b9849abf2009-11-25 19:13:197994 }
[email protected]f7a64ee2010-02-01 22:24:147995 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197996}
7997
[email protected]1c75a3702011-11-11 14:15:287998error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
vmiuracd108592014-09-08 14:36:347999 uint32 immediate_data_size,
8000 const void* cmd_data) {
8001 const gles2::cmds::PostSubBufferCHROMIUM& c =
8002 *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data);
[email protected]43ed3a72012-05-30 22:55:388003 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]a36ed4832014-04-24 16:40:278004 {
8005 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
8006 }
[email protected]b381ee32014-03-22 02:43:438007 if (!supports_post_sub_buffer_) {
[email protected]ab09b612013-03-11 22:11:518008 LOCAL_SET_GL_ERROR(
8009 GL_INVALID_OPERATION,
8010 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:288011 return error::kNoError;
8012 }
[email protected]8f9b8dd2013-09-12 18:05:138013 bool is_tracing;
8014 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
8015 &is_tracing);
8016 if (is_tracing) {
8017 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
8018 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
8019 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
8020 is_offscreen ? offscreen_size_ : surface_->GetSize());
8021 }
[email protected]7794d512012-04-17 20:36:498022 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:288023 return error::kNoError;
[email protected]7794d512012-04-17 20:36:498024 } else {
8025 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:288026 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:498027 }
[email protected]1c75a3702011-11-11 14:15:288028}
8029
[email protected]957f0642014-04-09 16:50:018030error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
8031 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348032 const void* cmd_data) {
8033 const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
8034 *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data);
[email protected]d286ebbc2014-07-03 17:19:108035 TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
8036 if (!ref) {
8037 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
8038 "glScheduleOverlayPlaneCHROMIUM",
8039 "unknown texture");
8040 return error::kNoError;
8041 }
8042 gfx::GLImage* image =
8043 ref->texture()->GetLevelImage(ref->texture()->target(), 0);
8044 if (!image) {
8045 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
8046 "glScheduleOverlayPlaneCHROMIUM",
8047 "unsupported texture format");
8048 return error::kNoError;
8049 }
8050 gfx::OverlayTransform transform = GetGFXOverlayTransform(c.plane_transform);
8051 if (transform == gfx::OVERLAY_TRANSFORM_INVALID) {
8052 LOCAL_SET_GL_ERROR(GL_INVALID_ENUM,
8053 "glScheduleOverlayPlaneCHROMIUM",
8054 "invalid transform enum");
8055 return error::kNoError;
8056 }
8057 if (!surface_->ScheduleOverlayPlane(
8058 c.plane_z_order,
8059 transform,
8060 image,
8061 gfx::Rect(c.bounds_x, c.bounds_y, c.bounds_width, c.bounds_height),
8062 gfx::RectF(c.uv_x, c.uv_y, c.uv_width, c.uv_height))) {
8063 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
8064 "glScheduleOverlayPlaneCHROMIUM",
8065 "failed to schedule overlay");
8066 }
[email protected]957f0642014-04-09 16:50:018067 return error::kNoError;
8068}
8069
[email protected]558847a2010-03-24 07:02:548070error::Error GLES2DecoderImpl::GetAttribLocationHelper(
8071 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8072 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578073 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518074 LOCAL_SET_GL_ERROR(
8075 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578076 return error::kNoError;
8077 }
[email protected]df37b9932013-03-08 05:21:428078 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:588079 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:428080 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148081 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198082 }
[email protected]df37b9932013-03-08 05:21:428083 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518084 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438085 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258086 return error::kNoError;
8087 }
[email protected]b9849abf2009-11-25 19:13:198088 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548089 location_shm_id, location_shm_offset, sizeof(GLint));
8090 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148091 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198092 }
[email protected]558847a2010-03-24 07:02:548093 // Require the client to init this incase the context is lost and we are no
8094 // longer executing commands.
8095 if (*location != -1) {
8096 return error::kGenericError;
8097 }
[email protected]df37b9932013-03-08 05:21:428098 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148099 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198100}
8101
[email protected]558847a2010-03-24 07:02:548102error::Error GLES2DecoderImpl::HandleGetAttribLocation(
vmiuracd108592014-09-08 14:36:348103 uint32 immediate_data_size,
8104 const void* cmd_data) {
8105 const gles2::cmds::GetAttribLocation& c =
8106 *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548107 Bucket* bucket = GetBucket(c.name_bucket_id);
8108 if (!bucket) {
8109 return error::kInvalidArguments;
8110 }
8111 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188112 if (!bucket->GetAsString(&name_str)) {
8113 return error::kInvalidArguments;
8114 }
[email protected]558847a2010-03-24 07:02:548115 return GetAttribLocationHelper(
8116 c.program, c.location_shm_id, c.location_shm_offset, name_str);
8117}
8118
8119error::Error GLES2DecoderImpl::GetUniformLocationHelper(
8120 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8121 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:578122 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:518123 LOCAL_SET_GL_ERROR(
8124 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:578125 return error::kNoError;
8126 }
[email protected]df37b9932013-03-08 05:21:428127 Program* program = GetProgramInfoNotShader(
[email protected]caa13ed2014-02-17 11:29:208128 client_id, "glGetUniformLocation");
[email protected]df37b9932013-03-08 05:21:428129 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:148130 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198131 }
[email protected]df37b9932013-03-08 05:21:428132 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:518133 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438134 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:258135 return error::kNoError;
8136 }
[email protected]b9849abf2009-11-25 19:13:198137 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:548138 location_shm_id, location_shm_offset, sizeof(GLint));
8139 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:148140 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198141 }
[email protected]558847a2010-03-24 07:02:548142 // Require the client to init this incase the context is lost an we are no
8143 // longer executing commands.
8144 if (*location != -1) {
8145 return error::kGenericError;
8146 }
[email protected]df37b9932013-03-08 05:21:428147 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:148148 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198149}
8150
[email protected]f7a64ee2010-02-01 22:24:148151error::Error GLES2DecoderImpl::HandleGetUniformLocation(
vmiuracd108592014-09-08 14:36:348152 uint32 immediate_data_size,
8153 const void* cmd_data) {
8154 const gles2::cmds::GetUniformLocation& c =
8155 *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data);
[email protected]558847a2010-03-24 07:02:548156 Bucket* bucket = GetBucket(c.name_bucket_id);
8157 if (!bucket) {
8158 return error::kInvalidArguments;
8159 }
8160 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:188161 if (!bucket->GetAsString(&name_str)) {
8162 return error::kInvalidArguments;
8163 }
[email protected]558847a2010-03-24 07:02:548164 return GetUniformLocationHelper(
8165 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:198166}
8167
zmo5393fb52015-01-27 01:50:488168error::Error GLES2DecoderImpl::GetFragDataLocationHelper(
8169 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
8170 const std::string& name_str) {
8171 GLint* location = GetSharedMemoryAs<GLint*>(
8172 location_shm_id, location_shm_offset, sizeof(GLint));
8173 if (!location) {
8174 return error::kOutOfBounds;
8175 }
8176 // Require the client to init this incase the context is lost and we are no
8177 // longer executing commands.
8178 if (*location != -1) {
8179 return error::kGenericError;
8180 }
8181 Program* program = GetProgramInfoNotShader(
8182 client_id, "glGetFragDataLocation");
8183 if (!program) {
8184 return error::kNoError;
8185 }
8186 *location = glGetFragDataLocation(program->service_id(), name_str.c_str());
8187 return error::kNoError;
8188}
8189
8190error::Error GLES2DecoderImpl::HandleGetFragDataLocation(
8191 uint32 immediate_data_size,
8192 const void* cmd_data) {
8193 if (!unsafe_es3_apis_enabled())
8194 return error::kUnknownCommand;
8195 const gles2::cmds::GetFragDataLocation& c =
8196 *static_cast<const gles2::cmds::GetFragDataLocation*>(cmd_data);
8197 Bucket* bucket = GetBucket(c.name_bucket_id);
8198 if (!bucket) {
8199 return error::kInvalidArguments;
8200 }
8201 std::string name_str;
8202 if (!bucket->GetAsString(&name_str)) {
8203 return error::kInvalidArguments;
8204 }
8205 return GetFragDataLocationHelper(
8206 c.program, c.location_shm_id, c.location_shm_offset, name_str);
8207}
8208
zmo4a16ff992015-02-05 22:18:418209error::Error GLES2DecoderImpl::HandleGetUniformBlockIndex(
8210 uint32 immediate_data_size, const void* cmd_data) {
8211 if (!unsafe_es3_apis_enabled())
8212 return error::kUnknownCommand;
8213 const gles2::cmds::GetUniformBlockIndex& c =
8214 *static_cast<const gles2::cmds::GetUniformBlockIndex*>(cmd_data);
8215 Bucket* bucket = GetBucket(c.name_bucket_id);
8216 if (!bucket) {
8217 return error::kInvalidArguments;
8218 }
8219 std::string name_str;
8220 if (!bucket->GetAsString(&name_str)) {
8221 return error::kInvalidArguments;
8222 }
8223 GLuint* index = GetSharedMemoryAs<GLuint*>(
8224 c.index_shm_id, c.index_shm_offset, sizeof(GLuint));
8225 if (!index) {
8226 return error::kOutOfBounds;
8227 }
8228 // Require the client to init this in case the context is lost and we are no
8229 // longer executing commands.
8230 if (*index != GL_INVALID_INDEX) {
8231 return error::kGenericError;
8232 }
8233 Program* program = GetProgramInfoNotShader(
8234 c.program, "glGetUniformBlockIndex");
8235 if (!program) {
8236 return error::kNoError;
8237 }
8238 *index = glGetUniformBlockIndex(program->service_id(), name_str.c_str());
8239 return error::kNoError;
8240}
8241
vmiuracd108592014-09-08 14:36:348242error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
8243 const void* cmd_data) {
8244 const gles2::cmds::GetString& c =
8245 *static_cast<const gles2::cmds::GetString*>(cmd_data);
[email protected]ddd968b82010-03-02 00:44:298246 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:058247 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:518248 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:298249 return error::kNoError;
8250 }
[email protected]959e9072013-09-20 16:58:388251 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:048252 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:158253 switch (name) {
8254 case GL_VERSION:
8255 str = "OpenGL ES 2.0 Chromium";
8256 break;
8257 case GL_SHADING_LANGUAGE_VERSION:
8258 str = "OpenGL ES GLSL ES 1.0 Chromium";
8259 break;
[email protected]32939602012-05-09 06:25:168260 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:168261 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:388262 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
8263 // They are used by WEBGL_debug_renderer_info.
8264 if (!force_webgl_glsl_validation_)
8265 str = "Chromium";
[email protected]32939602012-05-09 06:25:168266 break;
[email protected]1958e0e2010-04-22 05:17:158267 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:048268 {
[email protected]70dc60932013-06-04 03:33:498269 // For WebGL contexts, strip out the OES derivatives and
8270 // EXT frag depth extensions if they have not been enabled.
8271 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:048272 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:498273 if (!derivatives_explicitly_enabled_) {
8274 size_t offset = extensions.find(kOESDerivativeExtension);
8275 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098276 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:498277 std::string());
8278 }
8279 }
8280 if (!frag_depth_explicitly_enabled_) {
8281 size_t offset = extensions.find(kEXTFragDepthExtension);
8282 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098283 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:498284 std::string());
8285 }
[email protected]f0d74742011-10-03 16:31:048286 }
[email protected]aff39ac82013-06-08 04:53:138287 if (!draw_buffers_explicitly_enabled_) {
8288 size_t offset = extensions.find(kEXTDrawBuffersExtension);
8289 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:098290 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:138291 std::string());
8292 }
8293 }
[email protected]93c2fd82014-04-16 02:46:068294 if (!shader_texture_lod_explicitly_enabled_) {
8295 size_t offset = extensions.find(kEXTShaderTextureLodExtension);
8296 if (std::string::npos != offset) {
8297 extensions.replace(offset,
8298 arraysize(kEXTShaderTextureLodExtension),
8299 std::string());
8300 }
8301 }
[email protected]f0d74742011-10-03 16:31:048302 } else {
[email protected]6f5fac9d12012-06-26 21:02:458303 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:048304 }
[email protected]b381ee32014-03-22 02:43:438305 if (supports_post_sub_buffer_)
8306 extensions += " GL_CHROMIUM_post_sub_buffer";
[email protected]6f5fac9d12012-06-26 21:02:458307 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:048308 }
[email protected]1958e0e2010-04-22 05:17:158309 break;
8310 default:
[email protected]1958e0e2010-04-22 05:17:158311 break;
8312 }
[email protected]ddd968b82010-03-02 00:44:298313 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:158314 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:298315 return error::kNoError;
8316}
8317
vmiuracd108592014-09-08 14:36:348318error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size,
8319 const void* cmd_data) {
8320 const gles2::cmds::BufferData& c =
8321 *static_cast<const gles2::cmds::BufferData*>(cmd_data);
[email protected]0c86dbf2010-03-05 08:14:118322 GLenum target = static_cast<GLenum>(c.target);
8323 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
8324 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8325 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8326 GLenum usage = static_cast<GLenum>(c.usage);
8327 const void* data = NULL;
8328 if (data_shm_id != 0 || data_shm_offset != 0) {
8329 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
8330 if (!data) {
8331 return error::kOutOfBounds;
8332 }
8333 }
[email protected]0fbba3732013-07-17 15:40:138334 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:148335 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198336}
8337
[email protected]0c86dbf2010-03-05 08:14:118338void GLES2DecoderImpl::DoBufferSubData(
8339 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:138340 // Just delegate it. Some validation is actually done before this.
8341 buffer_manager()->ValidateAndDoBufferSubData(
8342 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:198343}
8344
[email protected]0d6bfdc2011-11-02 01:32:208345bool GLES2DecoderImpl::ClearLevel(
8346 unsigned service_id,
8347 unsigned bind_target,
8348 unsigned target,
8349 int level,
[email protected]d8e6c9242014-02-20 16:56:258350 unsigned internal_format,
[email protected]0d6bfdc2011-11-02 01:32:208351 unsigned format,
8352 unsigned type,
8353 int width,
[email protected]4502e6492011-12-14 19:39:158354 int height,
8355 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:008356 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:008357 if (feature_info_->feature_flags().angle_depth_texture &&
8358 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:008359 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
8360 // on depth formats.
8361 GLuint fb = 0;
8362 glGenFramebuffersEXT(1, &fb);
8363 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
8364
8365 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
8366 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
8367 GL_DEPTH_ATTACHMENT;
8368
8369 glFramebufferTexture2DEXT(
8370 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
8371 // ANGLE promises a depth only attachment ok.
8372 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
8373 GL_FRAMEBUFFER_COMPLETE) {
8374 return false;
8375 }
8376 glClearStencil(0);
[email protected]efc87712014-07-09 00:22:478377 state_.SetDeviceStencilMaskSeparate(GL_FRONT, kDefaultStencilMask);
8378 state_.SetDeviceStencilMaskSeparate(GL_BACK, kDefaultStencilMask);
[email protected]81375742012-06-08 00:04:008379 glClearDepth(1.0f);
[email protected]454157e2014-05-03 02:49:458380 state_.SetDeviceDepthMask(GL_TRUE);
8381 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]81375742012-06-08 00:04:008382 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
8383
8384 RestoreClearState();
8385
8386 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:358387 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:008388 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
8389 GLuint fb_service_id =
8390 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
8391 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
8392 return true;
8393 }
8394
[email protected]45d15a62012-04-18 14:33:178395 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
8396
8397 uint32 size;
8398 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:348399 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428400 width, height, 1, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:178401 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:208402 return false;
8403 }
[email protected]45d15a62012-04-18 14:33:178404
[email protected]a5d3dad2012-05-26 04:34:448405 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
8406
[email protected]45d15a62012-04-18 14:33:178407 int tile_height;
8408
8409 if (size > kMaxZeroSize) {
8410 if (kMaxZeroSize < padded_row_size) {
8411 // That'd be an awfully large texture.
8412 return false;
8413 }
8414 // We should never have a large total size with a zero row size.
8415 DCHECK_GT(padded_row_size, 0U);
8416 tile_height = kMaxZeroSize / padded_row_size;
8417 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428418 width, tile_height, 1, format, type, state_.unpack_alignment, &size,
[email protected]e259eb412012-10-13 05:47:248419 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:178420 return false;
8421 }
[email protected]4502e6492011-12-14 19:39:158422 } else {
[email protected]45d15a62012-04-18 14:33:178423 tile_height = height;
8424 }
8425
8426 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:558427 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:178428 memset(zero.get(), 0, size);
8429 glBindTexture(bind_target, service_id);
8430
8431 GLint y = 0;
8432 while (y < height) {
8433 GLint h = y + tile_height > height ? height - y : tile_height;
8434 if (is_texture_immutable || h != height) {
8435 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
8436 } else {
[email protected]8f1d2aa2013-05-10 23:45:388437 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:258438 target, level, internal_format, width, h, 0, format, type,
8439 zero.get());
[email protected]45d15a62012-04-18 14:33:178440 }
8441 y += tile_height;
[email protected]4502e6492011-12-14 19:39:158442 }
[email protected]c986af502013-08-14 01:04:448443 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
8444 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:078445 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:208446 return true;
8447}
8448
[email protected]ad84a3a2012-06-08 21:42:438449namespace {
8450
8451const int kS3TCBlockWidth = 4;
8452const int kS3TCBlockHeight = 4;
8453const int kS3TCDXT1BlockSize = 8;
8454const int kS3TCDXT3AndDXT5BlockSize = 16;
8455
8456bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:518457 return (size == 1) ||
8458 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:438459}
8460
[email protected]8aec81ec2014-04-29 01:04:518461bool IsValidPVRTCSize(GLint level, GLsizei size) {
[email protected]a07a23602014-08-05 11:36:128462 return GLES2Util::IsPOT(size);
[email protected]8aec81ec2014-04-29 01:04:518463}
8464
[email protected]ad84a3a2012-06-08 21:42:438465} // anonymous namespace.
8466
8467bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
8468 const char* function_name,
8469 GLsizei width, GLsizei height, GLenum format, size_t size) {
8470 unsigned int bytes_required = 0;
8471
8472 switch (format) {
[email protected]8aec81ec2014-04-29 01:04:518473 case GL_ATC_RGB_AMD:
[email protected]ad84a3a2012-06-08 21:42:438474 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
[email protected]8aec81ec2014-04-29 01:04:518475 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8476 case GL_ETC1_RGB8_OES: {
[email protected]ad84a3a2012-06-08 21:42:438477 int num_blocks_across =
8478 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8479 int num_blocks_down =
8480 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8481 int num_blocks = num_blocks_across * num_blocks_down;
8482 bytes_required = num_blocks * kS3TCDXT1BlockSize;
8483 break;
8484 }
[email protected]8aec81ec2014-04-29 01:04:518485 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8486 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
[email protected]ad84a3a2012-06-08 21:42:438487 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8488 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8489 int num_blocks_across =
8490 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
8491 int num_blocks_down =
8492 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
8493 int num_blocks = num_blocks_across * num_blocks_down;
8494 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
8495 break;
8496 }
[email protected]8aec81ec2014-04-29 01:04:518497 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8498 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: {
8499 bytes_required = (std::max(width, 8) * std::max(height, 8) * 4 + 7)/8;
8500 break;
8501 }
8502 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8503 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8504 bytes_required = (std::max(width, 16) * std::max(height, 8) * 2 + 7)/8;
[email protected]2d3765b2012-10-03 00:31:078505 break;
8506 }
[email protected]ad84a3a2012-06-08 21:42:438507 default:
[email protected]ab09b612013-03-11 22:11:518508 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:438509 return false;
8510 }
8511
8512 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:518513 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438514 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
8515 return false;
8516 }
8517
8518 return true;
8519}
8520
8521bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
8522 const char* function_name,
8523 GLint level, GLsizei width, GLsizei height, GLenum format) {
8524 switch (format) {
8525 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8526 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8527 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8528 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8529 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:518530 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438531 GL_INVALID_OPERATION, function_name,
8532 "width or height invalid for level");
8533 return false;
8534 }
8535 return true;
8536 }
[email protected]8aec81ec2014-04-29 01:04:518537 case GL_ATC_RGB_AMD:
8538 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8539 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
8540 case GL_ETC1_RGB8_OES: {
[email protected]2d3765b2012-10-03 00:31:078541 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:518542 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078543 GL_INVALID_OPERATION, function_name,
8544 "width or height invalid for level");
8545 return false;
8546 }
8547 return true;
[email protected]8aec81ec2014-04-29 01:04:518548 }
8549 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8550 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8551 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8552 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8553 if (!IsValidPVRTCSize(level, width) ||
8554 !IsValidPVRTCSize(level, height)) {
8555 LOCAL_SET_GL_ERROR(
8556 GL_INVALID_OPERATION, function_name,
8557 "width or height invalid for level");
8558 return false;
8559 }
8560 return true;
8561 }
[email protected]ad84a3a2012-06-08 21:42:438562 default:
8563 return false;
8564 }
8565}
8566
8567bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
8568 const char* function_name,
8569 GLenum target, GLint level, GLint xoffset, GLint yoffset,
8570 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:358571 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:438572 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:518573 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438574 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
8575 return false;
8576 }
8577
8578 switch (format) {
8579 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
8580 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
8581 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
8582 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
8583 const int kBlockWidth = 4;
8584 const int kBlockHeight = 4;
8585 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:518586 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438587 GL_INVALID_OPERATION, function_name,
8588 "xoffset or yoffset not multiple of 4");
8589 return false;
8590 }
8591 GLsizei tex_width = 0;
8592 GLsizei tex_height = 0;
8593 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8594 width - xoffset > tex_width ||
8595 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:518596 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438597 GL_INVALID_OPERATION, function_name, "dimensions out of range");
8598 return false;
8599 }
8600 return ValidateCompressedTexDimensions(
8601 function_name, level, width, height, format);
8602 }
[email protected]8aec81ec2014-04-29 01:04:518603 case GL_ATC_RGB_AMD:
8604 case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
8605 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: {
8606 LOCAL_SET_GL_ERROR(
8607 GL_INVALID_OPERATION, function_name,
8608 "not supported for ATC textures");
8609 return false;
8610 }
[email protected]2d3765b2012-10-03 00:31:078611 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:518612 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:078613 GL_INVALID_OPERATION, function_name,
[email protected]caa13ed2014-02-17 11:29:208614 "not supported for ECT1_RGB8_OES textures");
[email protected]2d3765b2012-10-03 00:31:078615 return false;
8616 }
[email protected]8aec81ec2014-04-29 01:04:518617 case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
8618 case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
8619 case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
8620 case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
8621 if ((xoffset != 0) || (yoffset != 0)) {
8622 LOCAL_SET_GL_ERROR(
8623 GL_INVALID_OPERATION, function_name,
8624 "xoffset and yoffset must be zero");
8625 return false;
8626 }
8627 GLsizei tex_width = 0;
8628 GLsizei tex_height = 0;
8629 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
8630 width != tex_width ||
8631 height != tex_height) {
8632 LOCAL_SET_GL_ERROR(
8633 GL_INVALID_OPERATION, function_name,
8634 "dimensions must match existing texture level dimensions");
8635 return false;
8636 }
8637 return ValidateCompressedTexDimensions(
8638 function_name, level, width, height, format);
8639 }
[email protected]ad84a3a2012-06-08 21:42:438640 default:
8641 return false;
8642 }
8643}
8644
[email protected]a93bb842010-02-16 23:03:478645error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
8646 GLenum target,
8647 GLint level,
8648 GLenum internal_format,
8649 GLsizei width,
8650 GLsizei height,
8651 GLint border,
8652 GLsizei image_size,
8653 const void* data) {
[email protected]a93bb842010-02-16 23:03:478654 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:058655 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518656 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8657 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:298658 return error::kNoError;
8659 }
[email protected]9438b012010-06-15 22:55:058660 if (!validators_->compressed_texture_format.IsValid(
8661 internal_format)) {
[email protected]ab09b612013-03-11 22:11:518662 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538663 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:478664 return error::kNoError;
8665 }
[email protected]80eb6b52012-01-19 00:14:418666 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:478667 border != 0) {
[email protected]ab09b612013-03-11 22:11:518668 LOCAL_SET_GL_ERROR(
8669 GL_INVALID_VALUE,
8670 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:478671 return error::kNoError;
8672 }
[email protected]c986af502013-08-14 01:04:448673 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8674 &state_, target);
[email protected]370eaf12013-05-18 09:19:498675 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518676 LOCAL_SET_GL_ERROR(
8677 GL_INVALID_VALUE,
8678 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:478679 return error::kNoError;
8680 }
[email protected]370eaf12013-05-18 09:19:498681 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078682 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518683 LOCAL_SET_GL_ERROR(
8684 GL_INVALID_OPERATION,
8685 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:438686 return error::kNoError;
8687 }
8688
8689 if (!ValidateCompressedTexDimensions(
8690 "glCompressedTexImage2D", level, width, height, internal_format) ||
8691 !ValidateCompressedTexFuncData(
8692 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:178693 return error::kNoError;
8694 }
[email protected]968351b2011-12-20 08:26:518695
[email protected]7989c9e2013-01-23 06:39:268696 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:518697 LOCAL_SET_GL_ERROR(
8698 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268699 return error::kNoError;
8700 }
8701
[email protected]02965c22013-03-09 02:40:078702 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448703 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:518704 }
8705
[email protected]40d90a22013-04-09 03:39:558706 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:478707 if (!data) {
8708 zero.reset(new int8[image_size]);
8709 memset(zero.get(), 0, image_size);
8710 data = zero.get();
8711 }
[email protected]ab09b612013-03-11 22:11:518712 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:478713 glCompressedTexImage2D(
8714 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:518715 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438716 if (error == GL_NO_ERROR) {
8717 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498718 texture_ref, target, level, internal_format,
8719 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:438720 }
vmiura8266ca72014-09-09 21:37:008721
8722 // This may be a slow command. Exit command processing to allow for
8723 // context preemption and GPU watchdog checks.
8724 ExitCommandProcessingEarly();
[email protected]a93bb842010-02-16 23:03:478725 return error::kNoError;
8726}
8727
[email protected]f7a64ee2010-02-01 22:24:148728error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
vmiuracd108592014-09-08 14:36:348729 uint32 immediate_data_size,
8730 const void* cmd_data) {
8731 const gles2::cmds::CompressedTexImage2D& c =
8732 *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data);
[email protected]b9849abf2009-11-25 19:13:198733 GLenum target = static_cast<GLenum>(c.target);
8734 GLint level = static_cast<GLint>(c.level);
8735 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8736 GLsizei width = static_cast<GLsizei>(c.width);
8737 GLsizei height = static_cast<GLsizei>(c.height);
8738 GLint border = static_cast<GLint>(c.border);
8739 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
8740 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8741 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8742 const void* data = NULL;
8743 if (data_shm_id != 0 || data_shm_offset != 0) {
8744 data = GetSharedMemoryAs<const void*>(
8745 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:468746 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:148747 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198748 }
8749 }
[email protected]a93bb842010-02-16 23:03:478750 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:198751 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:198752}
8753
[email protected]b6140d02010-05-17 14:47:168754error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
vmiuracd108592014-09-08 14:36:348755 uint32 immediate_data_size,
8756 const void* cmd_data) {
8757 const gles2::cmds::CompressedTexImage2DBucket& c =
8758 *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168759 GLenum target = static_cast<GLenum>(c.target);
8760 GLint level = static_cast<GLint>(c.level);
8761 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8762 GLsizei width = static_cast<GLsizei>(c.width);
8763 GLsizei height = static_cast<GLsizei>(c.height);
8764 GLint border = static_cast<GLint>(c.border);
8765 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288766 if (!bucket) {
8767 return error::kInvalidArguments;
8768 }
8769 uint32 data_size = bucket->size();
8770 GLsizei imageSize = data_size;
8771 const void* data = bucket->GetData(0, data_size);
8772 if (!data) {
8773 return error::kInvalidArguments;
8774 }
[email protected]b6140d02010-05-17 14:47:168775 return DoCompressedTexImage2D(
8776 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:288777 imageSize, data);
[email protected]b6140d02010-05-17 14:47:168778}
8779
8780error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8781 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:348782 const void* cmd_data) {
8783 const gles2::cmds::CompressedTexSubImage2DBucket& c =
8784 *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data);
[email protected]b6140d02010-05-17 14:47:168785 GLenum target = static_cast<GLenum>(c.target);
8786 GLint level = static_cast<GLint>(c.level);
8787 GLint xoffset = static_cast<GLint>(c.xoffset);
8788 GLint yoffset = static_cast<GLint>(c.yoffset);
8789 GLsizei width = static_cast<GLsizei>(c.width);
8790 GLsizei height = static_cast<GLsizei>(c.height);
8791 GLenum format = static_cast<GLenum>(c.format);
8792 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288793 if (!bucket) {
8794 return error::kInvalidArguments;
8795 }
[email protected]b6140d02010-05-17 14:47:168796 uint32 data_size = bucket->size();
8797 GLsizei imageSize = data_size;
8798 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:288799 if (!data) {
8800 return error::kInvalidArguments;
8801 }
[email protected]9438b012010-06-15 22:55:058802 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518803 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:538804 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:168805 return error::kNoError;
8806 }
[email protected]9438b012010-06-15 22:55:058807 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518808 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8809 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:058810 return error::kNoError;
8811 }
[email protected]b6140d02010-05-17 14:47:168812 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518813 LOCAL_SET_GL_ERROR(
8814 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:168815 return error::kNoError;
8816 }
8817 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518818 LOCAL_SET_GL_ERROR(
8819 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:168820 return error::kNoError;
8821 }
8822 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:518823 LOCAL_SET_GL_ERROR(
8824 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:168825 return error::kNoError;
8826 }
[email protected]cadde4a2010-07-31 17:10:438827 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:168828 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8829 return error::kNoError;
8830}
8831
vmiuracd108592014-09-08 14:36:348832error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size,
8833 const void* cmd_data) {
8834 const gles2::cmds::TexImage2D& c =
8835 *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:138836 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
8837 "width", c.width, "height", c.height);
[email protected]c986af502013-08-14 01:04:448838 // Set as failed for now, but if it successed, this will be set to not failed.
8839 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:198840 GLenum target = static_cast<GLenum>(c.target);
8841 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:448842 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8843 // for internalformat.
8844 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198845 GLsizei width = static_cast<GLsizei>(c.width);
8846 GLsizei height = static_cast<GLsizei>(c.height);
8847 GLint border = static_cast<GLint>(c.border);
8848 GLenum format = static_cast<GLenum>(c.format);
8849 GLenum type = static_cast<GLenum>(c.type);
8850 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8851 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188852 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348853 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:428854 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
8855 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:188856 return error::kOutOfBounds;
8857 }
[email protected]b9849abf2009-11-25 19:13:198858 const void* pixels = NULL;
8859 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8860 pixels = GetSharedMemoryAs<const void*>(
8861 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468862 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148863 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198864 }
8865 }
[email protected]f598f422012-12-07 08:30:038866
[email protected]c986af502013-08-14 01:04:448867 TextureManager::DoTextImage2DArguments args = {
8868 target, level, internal_format, width, height, border, format, type,
8869 pixels, pixels_size};
8870 texture_manager()->ValidateAndDoTexImage2D(
8871 &texture_state_, &state_, &framebuffer_state_, args);
vmiura8266ca72014-09-09 21:37:008872
8873 // This may be a slow command. Exit command processing to allow for
8874 // context preemption and GPU watchdog checks.
8875 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:038876 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198877}
8878
zmobcadd6592015-01-08 20:13:428879error::Error GLES2DecoderImpl::HandleTexImage3D(uint32 immediate_data_size,
8880 const void* cmd_data) {
8881 // TODO(zmo): Unsafe ES3 API.
8882 if (!unsafe_es3_apis_enabled())
8883 return error::kUnknownCommand;
8884
8885 const gles2::cmds::TexImage3D& c =
8886 *static_cast<const gles2::cmds::TexImage3D*>(cmd_data);
8887 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage3D",
8888 "widthXheight", c.width * c.height, "depth", c.depth);
8889 GLenum target = static_cast<GLenum>(c.target);
8890 GLint level = static_cast<GLint>(c.level);
8891 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8892 GLsizei width = static_cast<GLsizei>(c.width);
8893 GLsizei height = static_cast<GLsizei>(c.height);
8894 GLsizei depth = static_cast<GLsizei>(c.depth);
8895 GLint border = static_cast<GLint>(c.border);
8896 GLenum format = static_cast<GLenum>(c.format);
8897 GLenum type = static_cast<GLenum>(c.type);
8898 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8899 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
8900 uint32 pixels_size;
8901 if (!GLES2Util::ComputeImageDataSizes(
8902 width, height, depth, format, type, state_.unpack_alignment, &pixels_size,
8903 NULL, NULL)) {
8904 return error::kOutOfBounds;
8905 }
8906 const void* pixels = NULL;
8907 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8908 pixels = GetSharedMemoryAs<const void*>(
8909 pixels_shm_id, pixels_shm_offset, pixels_size);
8910 if (!pixels) {
8911 return error::kOutOfBounds;
8912 }
8913 }
8914
8915 glTexImage3D(target, level, internal_format, width, height, depth, border,
8916 format, type, pixels);
8917
8918 // This may be a slow command. Exit command processing to allow for
8919 // context preemption and GPU watchdog checks.
8920 ExitCommandProcessingEarly();
8921 return error::kNoError;
8922}
8923
[email protected]cadde4a2010-07-31 17:10:438924void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8925 GLenum target,
8926 GLint level,
8927 GLint xoffset,
8928 GLint yoffset,
8929 GLsizei width,
8930 GLsizei height,
8931 GLenum format,
8932 GLsizei image_size,
8933 const void * data) {
[email protected]c986af502013-08-14 01:04:448934 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8935 &state_, target);
[email protected]370eaf12013-05-18 09:19:498936 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518937 LOCAL_SET_GL_ERROR(
8938 GL_INVALID_OPERATION,
8939 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438940 return;
8941 }
[email protected]370eaf12013-05-18 09:19:498942 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438943 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:528944 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078945 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518946 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528947 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438948 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:528949 return;
8950 }
8951 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:518952 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528953 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438954 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:528955 return;
8956 }
[email protected]02965c22013-03-09 02:40:078957 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:528958 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:518959 LOCAL_SET_GL_ERROR(
8960 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438961 return;
8962 }
[email protected]ad84a3a2012-06-08 21:42:438963
8964 if (!ValidateCompressedTexFuncData(
8965 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8966 !ValidateCompressedTexSubDimensions(
8967 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:078968 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:438969 return;
8970 }
8971
8972
[email protected]0d6bfdc2011-11-02 01:32:208973 // Note: There is no need to deal with texture cleared tracking here
8974 // because the validation above means you can only get here if the level
8975 // is already a matching compressed format and in that case
8976 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:438977 glCompressedTexSubImage2D(
8978 target, level, xoffset, yoffset, width, height, format, image_size, data);
vmiura8266ca72014-09-09 21:37:008979
8980 // This may be a slow command. Exit command processing to allow for
8981 // context preemption and GPU watchdog checks.
8982 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:438983}
8984
[email protected]6e288612010-12-21 20:45:038985static void Clip(
8986 GLint start, GLint range, GLint sourceRange,
8987 GLint* out_start, GLint* out_range) {
8988 DCHECK(out_start);
8989 DCHECK(out_range);
8990 if (start < 0) {
8991 range += start;
8992 start = 0;
8993 }
8994 GLint end = start + range;
8995 if (end > sourceRange) {
8996 range -= end - sourceRange;
8997 }
8998 *out_start = start;
8999 *out_range = range;
9000}
9001
[email protected]cadde4a2010-07-31 17:10:439002void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:449003 GLenum target,
9004 GLint level,
9005 GLenum internal_format,
9006 GLint x,
9007 GLint y,
9008 GLsizei width,
9009 GLsizei height,
9010 GLint border) {
[email protected]09e17272012-11-30 10:30:449011 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:449012 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9013 &state_, target);
[email protected]370eaf12013-05-18 09:19:499014 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519015 LOCAL_SET_GL_ERROR(
9016 GL_INVALID_OPERATION,
9017 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439018 return;
9019 }
[email protected]370eaf12013-05-18 09:19:499020 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079021 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519022 LOCAL_SET_GL_ERROR(
9023 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]cedee332014-05-23 07:07:539024 return;
[email protected]97dc7cbe2011-12-06 17:26:179025 }
[email protected]80eb6b52012-01-19 00:14:419026 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:189027 border != 0) {
[email protected]ab09b612013-03-11 22:11:519028 LOCAL_SET_GL_ERROR(
9029 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:189030 return;
9031 }
[email protected]17a961192014-02-14 15:20:529032 if (!texture_manager()->ValidateFormatAndTypeCombination(
9033 state_.GetErrorState(), "glCopyTexImage2D", internal_format,
9034 GL_UNSIGNED_BYTE)) {
[email protected]81375742012-06-08 00:04:009035 return;
9036 }
[email protected]f5719fb2010-08-04 18:27:189037
[email protected]9edc6b22010-12-23 02:00:269038 // Check we have compatible formats.
9039 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
9040 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
9041 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
9042
9043 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:519044 LOCAL_SET_GL_ERROR(
9045 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:269046 return;
9047 }
9048
[email protected]81375742012-06-08 00:04:009049 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519050 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009051 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:269052 "glCopyTexImage2D", "can not be used with depth or stencil textures");
9053 return;
9054 }
9055
9056 uint32 estimated_size = 0;
9057 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429058 width, height, 1, internal_format, GL_UNSIGNED_BYTE,
9059 state_.unpack_alignment, &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:519060 LOCAL_SET_GL_ERROR(
9061 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269062 return;
9063 }
9064
9065 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519066 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:009067 return;
9068 }
9069
[email protected]2ea5950d2014-07-09 18:20:349070 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexImage2D")) {
9071 return;
9072 }
9073
zmo383512cf2014-10-14 00:11:009074 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
9075 LOCAL_SET_GL_ERROR(
9076 GL_INVALID_OPERATION,
9077 "glCopyTexImage2D", "source and destination textures are the same");
9078 return;
9079 }
9080
[email protected]a0b78dc2011-11-11 10:43:109081 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
9082 return;
9083 }
9084
[email protected]ab09b612013-03-11 22:11:519085 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:279086 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:039087 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:269088
[email protected]02965c22013-03-09 02:40:079089 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:449090 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:469091 }
9092
[email protected]9edc6b22010-12-23 02:00:269093 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:039094 GLint copyX = 0;
9095 GLint copyY = 0;
9096 GLint copyWidth = 0;
9097 GLint copyHeight = 0;
9098 Clip(x, width, size.width(), &copyX, &copyWidth);
9099 Clip(y, height, size.height(), &copyY, &copyHeight);
9100
9101 if (copyX != x ||
9102 copyY != y ||
9103 copyWidth != width ||
9104 copyHeight != height) {
9105 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:209106 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:079107 texture->service_id(), texture->target(),
[email protected]d8e6c9242014-02-20 16:56:259108 target, level, internal_format, internal_format, GL_UNSIGNED_BYTE,
9109 width, height, texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:519110 LOCAL_SET_GL_ERROR(
9111 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:039112 return;
9113 }
[email protected]6e288612010-12-21 20:45:039114 if (copyHeight > 0 && copyWidth > 0) {
9115 GLint dx = copyX - x;
9116 GLint dy = copyY - y;
9117 GLint destX = dx;
9118 GLint destY = dy;
[email protected]00c2cf92014-03-14 00:08:379119 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039120 glCopyTexSubImage2D(target, level,
9121 destX, destY, copyX, copyY,
9122 copyWidth, copyHeight);
9123 }
9124 } else {
[email protected]00c2cf92014-03-14 00:08:379125 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039126 glCopyTexImage2D(target, level, internal_format,
9127 copyX, copyY, copyWidth, copyHeight, border);
9128 }
[email protected]ab09b612013-03-11 22:11:519129 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:439130 if (error == GL_NO_ERROR) {
9131 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499132 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:209133 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:439134 }
vmiura8266ca72014-09-09 21:37:009135
9136 // This may be a slow command. Exit command processing to allow for
9137 // context preemption and GPU watchdog checks.
9138 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439139}
9140
9141void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:449142 GLenum target,
9143 GLint level,
9144 GLint xoffset,
9145 GLint yoffset,
9146 GLint x,
9147 GLint y,
9148 GLsizei width,
9149 GLsizei height) {
[email protected]09e17272012-11-30 10:30:449150 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:449151 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9152 &state_, target);
[email protected]370eaf12013-05-18 09:19:499153 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519154 LOCAL_SET_GL_ERROR(
9155 GL_INVALID_OPERATION,
9156 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:439157 return;
9158 }
[email protected]370eaf12013-05-18 09:19:499159 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:439160 GLenum type = 0;
9161 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:079162 if (!texture->GetLevelType(target, level, &type, &format) ||
9163 !texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529164 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519165 LOCAL_SET_GL_ERROR(
9166 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:439167 return;
9168 }
[email protected]85a4ac22013-05-31 01:58:479169 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:519170 LOCAL_SET_GL_ERROR(
9171 GL_INVALID_OPERATION,
9172 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:599173 return;
9174 }
[email protected]9edc6b22010-12-23 02:00:269175
9176 // Check we have compatible formats.
9177 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
9178 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
9179 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
9180
[email protected]2d3765b2012-10-03 00:31:079181 if (!channels_needed ||
9182 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:519183 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439184 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:269185 return;
9186 }
9187
[email protected]81375742012-06-08 00:04:009188 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519189 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009190 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439191 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:009192 return;
9193 }
9194
[email protected]2ea5950d2014-07-09 18:20:349195 if (!CheckBoundReadFramebufferColorAttachment("glCopyTexSubImage2D")) {
9196 return;
9197 }
9198
zmo383512cf2014-10-14 00:11:009199 if (FormsTextureCopyingFeedbackLoop(texture_ref, level)) {
9200 LOCAL_SET_GL_ERROR(
9201 GL_INVALID_OPERATION,
9202 "glCopyTexSubImage2D", "source and destination textures are the same");
9203 return;
9204 }
9205
[email protected]a0b78dc2011-11-11 10:43:109206 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
9207 return;
9208 }
9209
[email protected]de26b3c2011-08-03 21:54:279210 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:039211 gfx::Size size = GetBoundReadFrameBufferSize();
9212 GLint copyX = 0;
9213 GLint copyY = 0;
9214 GLint copyWidth = 0;
9215 GLint copyHeight = 0;
9216 Clip(x, width, size.width(), &copyX, &copyWidth);
9217 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:209218
dongseong.hwang351519f2015-01-21 14:33:599219 if (xoffset != 0 || yoffset != 0 || width != size.width() ||
9220 height != size.height()) {
9221 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target,
9222 level)) {
9223 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexSubImage2D",
9224 "dimensions too big");
9225 return;
9226 }
9227 } else {
9228 // Write all pixels in below.
9229 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]0d6bfdc2011-11-02 01:32:209230 }
9231
[email protected]6e288612010-12-21 20:45:039232 if (copyX != x ||
9233 copyY != y ||
9234 copyWidth != width ||
9235 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:209236 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:039237 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:349238 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429239 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
[email protected]e259eb412012-10-13 05:47:249240 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:519241 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439242 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:039243 return;
9244 }
[email protected]40d90a22013-04-09 03:39:559245 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:039246 memset(zero.get(), 0, pixels_size);
[email protected]00c2cf92014-03-14 00:08:379247 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039248 glTexSubImage2D(
9249 target, level, xoffset, yoffset, width, height,
9250 format, type, zero.get());
9251 }
[email protected]0d6bfdc2011-11-02 01:32:209252
[email protected]6e288612010-12-21 20:45:039253 if (copyHeight > 0 && copyWidth > 0) {
9254 GLint dx = copyX - x;
9255 GLint dy = copyY - y;
9256 GLint destX = xoffset + dx;
9257 GLint destY = yoffset + dy;
[email protected]00c2cf92014-03-14 00:08:379258 ScopedModifyPixels modify(texture_ref);
[email protected]6e288612010-12-21 20:45:039259 glCopyTexSubImage2D(target, level,
9260 destX, destY, copyX, copyY,
9261 copyWidth, copyHeight);
9262 }
vmiura8266ca72014-09-09 21:37:009263
9264 // This may be a slow command. Exit command processing to allow for
9265 // context preemption and GPU watchdog checks.
9266 ExitCommandProcessingEarly();
[email protected]cadde4a2010-07-31 17:10:439267}
9268
[email protected]f598f422012-12-07 08:30:039269bool GLES2DecoderImpl::ValidateTexSubImage2D(
9270 error::Error* error,
9271 const char* function_name,
9272 GLenum target,
9273 GLint level,
9274 GLint xoffset,
9275 GLint yoffset,
9276 GLsizei width,
9277 GLsizei height,
9278 GLenum format,
9279 GLenum type,
9280 const void * data) {
9281 (*error) = error::kNoError;
9282 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:519283 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:039284 return false;
9285 }
9286 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:519287 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:039288 return false;
9289 }
9290 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:519291 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:039292 return false;
9293 }
[email protected]c986af502013-08-14 01:04:449294 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9295 &state_, target);
[email protected]370eaf12013-05-18 09:19:499296 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519297 LOCAL_SET_GL_ERROR(
9298 GL_INVALID_OPERATION,
9299 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:039300 return false;
[email protected]cadde4a2010-07-31 17:10:439301 }
[email protected]370eaf12013-05-18 09:19:499302 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:529303 GLenum current_type = 0;
9304 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:079305 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:519306 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:039307 GL_INVALID_OPERATION, function_name, "level does not exist.");
9308 return false;
[email protected]df6cf1ad2011-01-29 01:20:529309 }
[email protected]17a961192014-02-14 15:20:529310 if (!texture_manager()->ValidateTextureParameters(state_.GetErrorState(),
9311 function_name, format, type, internal_format, level)) {
[email protected]f598f422012-12-07 08:30:039312 return false;
[email protected]df6cf1ad2011-01-29 01:20:529313 }
9314 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:519315 LOCAL_SET_GL_ERROR(
9316 GL_INVALID_OPERATION,
9317 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:039318 return false;
[email protected]df6cf1ad2011-01-29 01:20:529319 }
[email protected]85a4ac22013-05-31 01:58:479320 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:519321 LOCAL_SET_GL_ERROR(
9322 GL_INVALID_OPERATION,
9323 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:599324 return false;
9325 }
[email protected]02965c22013-03-09 02:40:079326 if (!texture->ValidForTexture(
[email protected]17a961192014-02-14 15:20:529327 target, level, xoffset, yoffset, width, height, type)) {
[email protected]ab09b612013-03-11 22:11:519328 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:039329 return false;
[email protected]cadde4a2010-07-31 17:10:439330 }
[email protected]81375742012-06-08 00:04:009331 if ((GLES2Util::GetChannelsForFormat(format) &
9332 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:519333 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:009334 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:039335 function_name, "can not supply data for depth or stencil textures");
9336 return false;
[email protected]81375742012-06-08 00:04:009337 }
[email protected]f598f422012-12-07 08:30:039338 if (data == NULL) {
9339 (*error) = error::kOutOfBounds;
9340 return false;
9341 }
9342 return true;
9343}
[email protected]81375742012-06-08 00:04:009344
[email protected]f598f422012-12-07 08:30:039345error::Error GLES2DecoderImpl::DoTexSubImage2D(
9346 GLenum target,
9347 GLint level,
9348 GLint xoffset,
9349 GLint yoffset,
9350 GLsizei width,
9351 GLsizei height,
9352 GLenum format,
9353 GLenum type,
9354 const void * data) {
9355 error::Error error = error::kNoError;
9356 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
9357 xoffset, yoffset, width, height, format, type, data)) {
9358 return error;
9359 }
[email protected]c986af502013-08-14 01:04:449360 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9361 &state_, target);
[email protected]370eaf12013-05-18 09:19:499362 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:159363 GLsizei tex_width = 0;
9364 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:079365 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:159366 DCHECK(ok);
9367 if (xoffset != 0 || yoffset != 0 ||
9368 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:499369 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
9370 target, level)) {
[email protected]ab09b612013-03-11 22:11:519371 LOCAL_SET_GL_ERROR(
9372 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:039373 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:309374 }
[email protected]c986af502013-08-14 01:04:449375 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159376 glTexSubImage2D(
9377 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:039378 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:209379 }
[email protected]4502e6492011-12-14 19:39:159380
[email protected]345ba902013-11-14 21:39:009381 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
[email protected]c986af502013-08-14 01:04:449382 !texture->IsImmutable()) {
9383 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]d8e6c9242014-02-20 16:56:259384 GLenum internal_format;
9385 GLenum tex_type;
9386 texture->GetLevelType(target, level, &tex_type, &internal_format);
9387 // NOTE: In OpenGL ES 2.0 border is always zero. If that changes we'll need
9388 // to look it up.
[email protected]8f1d2aa2013-05-10 23:45:389389 glTexImage2D(
[email protected]d8e6c9242014-02-20 16:56:259390 target, level, internal_format, width, height, 0, format, type, data);
[email protected]4502e6492011-12-14 19:39:159391 } else {
[email protected]c986af502013-08-14 01:04:449392 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:159393 glTexSubImage2D(
9394 target, level, xoffset, yoffset, width, height, format, type, data);
9395 }
[email protected]370eaf12013-05-18 09:19:499396 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
vmiura8266ca72014-09-09 21:37:009397
9398 // This may be a slow command. Exit command processing to allow for
9399 // context preemption and GPU watchdog checks.
9400 ExitCommandProcessingEarly();
[email protected]f598f422012-12-07 08:30:039401 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:439402}
9403
vmiuracd108592014-09-08 14:36:349404error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
9405 const void* cmd_data) {
9406 const gles2::cmds::TexSubImage2D& c =
9407 *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
[email protected]67f929422014-05-17 15:33:139408 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
9409 "width", c.width, "height", c.height);
[email protected]b493ee622011-04-13 23:52:009410 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:449411 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:009412 return error::kNoError;
9413
9414 GLenum target = static_cast<GLenum>(c.target);
9415 GLint level = static_cast<GLint>(c.level);
9416 GLint xoffset = static_cast<GLint>(c.xoffset);
9417 GLint yoffset = static_cast<GLint>(c.yoffset);
9418 GLsizei width = static_cast<GLsizei>(c.width);
9419 GLsizei height = static_cast<GLsizei>(c.height);
9420 GLenum format = static_cast<GLenum>(c.format);
9421 GLenum type = static_cast<GLenum>(c.type);
9422 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:349423 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:429424 width, height, 1, format, type, state_.unpack_alignment, &data_size,
[email protected]e259eb412012-10-13 05:47:249425 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:009426 return error::kOutOfBounds;
9427 }
9428 const void* pixels = GetSharedMemoryAs<const void*>(
9429 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:039430 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:009431 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:009432}
9433
zmobcadd6592015-01-08 20:13:429434// TODO(zmo): Remove the below stub once we add the real function binding.
9435// Currently it's missing due to a gmock limitation.
9436static void glTexSubImage3D(
9437 GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
9438 GLsizei height, GLsizei width, GLsizei depth, GLenum format, GLenum type,
9439 const void* pixels) {
9440 NOTIMPLEMENTED();
9441}
9442
9443error::Error GLES2DecoderImpl::HandleTexSubImage3D(uint32 immediate_data_size,
9444 const void* cmd_data) {
9445 // TODO(zmo): Unsafe ES3 API.
9446 if (!unsafe_es3_apis_enabled())
9447 return error::kUnknownCommand;
9448
9449 const gles2::cmds::TexSubImage3D& c =
9450 *static_cast<const gles2::cmds::TexSubImage3D*>(cmd_data);
9451 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage3D",
9452 "widthXheight", c.width * c.height, "depth", c.depth);
9453 GLenum target = static_cast<GLenum>(c.target);
9454 GLint level = static_cast<GLint>(c.level);
9455 GLint xoffset = static_cast<GLint>(c.xoffset);
9456 GLint yoffset = static_cast<GLint>(c.yoffset);
9457 GLint zoffset = static_cast<GLint>(c.zoffset);
9458 GLsizei width = static_cast<GLsizei>(c.width);
9459 GLsizei height = static_cast<GLsizei>(c.height);
9460 GLsizei depth = static_cast<GLsizei>(c.depth);
9461 GLenum format = static_cast<GLenum>(c.format);
9462 GLenum type = static_cast<GLenum>(c.type);
9463 uint32 data_size;
9464 if (!GLES2Util::ComputeImageDataSizes(
9465 width, height, depth, format, type, state_.unpack_alignment, &data_size,
9466 NULL, NULL)) {
9467 return error::kOutOfBounds;
9468 }
9469 const void* pixels = GetSharedMemoryAs<const void*>(
9470 c.pixels_shm_id, c.pixels_shm_offset, data_size);
9471 glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height,
9472 depth, format, type, pixels);
9473 return error::kNoError;
9474}
9475
[email protected]f7a64ee2010-02-01 22:24:149476error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
vmiuracd108592014-09-08 14:36:349477 uint32 immediate_data_size,
9478 const void* cmd_data) {
9479 const gles2::cmds::GetVertexAttribPointerv& c =
9480 *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data);
[email protected]8bf5a3e2010-01-29 04:21:369481 GLuint index = static_cast<GLuint>(c.index);
9482 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:359483 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:259484 Result* result = GetSharedMemoryAs<Result*>(
9485 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:369486 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:149487 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:369488 }
[email protected]07d0cc82010-02-17 04:51:409489 // Check that the client initialized the result.
9490 if (result->size != 0) {
9491 return error::kInvalidArguments;
9492 }
[email protected]9438b012010-06-15 22:55:059493 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:519494 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9495 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:149496 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369497 }
[email protected]3916c97e2010-02-25 03:20:509498 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:519499 LOCAL_SET_GL_ERROR(
9500 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:149501 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:369502 }
[email protected]0bfd9882010-02-05 23:02:259503 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:089504 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:359505 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:149506 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329507}
9508
[email protected]f7b85372010-02-03 01:11:379509bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:429510 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:379511 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:129512 error::Error* error, GLint* real_location,
9513 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:109514 DCHECK(error);
9515 DCHECK(service_id);
9516 DCHECK(result_pointer);
9517 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:129518 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:379519 *error = error::kNoError;
9520 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:259521 SizedResult<GLint>* result;
9522 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9523 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
9524 if (!result) {
[email protected]f7b85372010-02-03 01:11:379525 *error = error::kOutOfBounds;
9526 return false;
9527 }
[email protected]0bfd9882010-02-05 23:02:259528 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:379529 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:259530 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:429531 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
9532 if (!program) {
[email protected]ae51d192010-04-27 00:48:039533 return false;
9534 }
[email protected]df37b9932013-03-08 05:21:429535 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:379536 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:519537 LOCAL_SET_GL_ERROR(
9538 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:379539 return false;
9540 }
[email protected]df37b9932013-03-08 05:21:429541 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:369542 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:359543 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429544 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:129545 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:369546 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:379547 // No such location.
[email protected]ab09b612013-03-11 22:11:519548 LOCAL_SET_GL_ERROR(
9549 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:379550 return false;
9551 }
[email protected]43c2f1f2011-03-25 18:35:369552 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:509553 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:379554 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:519555 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:379556 return false;
9557 }
[email protected]0bfd9882010-02-05 23:02:259558 result = GetSharedMemoryAs<SizedResult<GLint>*>(
9559 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
9560 if (!result) {
[email protected]f7b85372010-02-03 01:11:379561 *error = error::kOutOfBounds;
9562 return false;
9563 }
[email protected]0bfd9882010-02-05 23:02:259564 result->size = size;
[email protected]939e7362010-05-13 20:49:109565 *result_type = type;
[email protected]f7b85372010-02-03 01:11:379566 return true;
9567}
9568
vmiuracd108592014-09-08 14:36:349569error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size,
9570 const void* cmd_data) {
9571 const gles2::cmds::GetUniformiv& c =
9572 *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379573 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339574 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379575 GLuint service_id;
[email protected]939e7362010-05-13 20:49:109576 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:129577 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379578 Error error;
[email protected]0bfd9882010-02-05 23:02:259579 void* result;
[email protected]f7b85372010-02-03 01:11:379580 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129581 program, fake_location, c.params_shm_id, c.params_shm_offset,
9582 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:259583 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:129584 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:359585 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:379586 }
9587 return error;
[email protected]96449d2c2009-11-25 00:01:329588}
9589
vmiuracd108592014-09-08 14:36:349590error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size,
9591 const void* cmd_data) {
9592 const gles2::cmds::GetUniformfv& c =
9593 *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data);
[email protected]f7b85372010-02-03 01:11:379594 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:339595 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:379596 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:129597 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:379598 Error error;
[email protected]ed9f9cd2013-02-27 21:12:359599 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:109600 Result* result;
9601 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:379602 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:129603 program, fake_location, c.params_shm_id, c.params_shm_offset,
9604 &error, &real_location, &service_id,
9605 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:109606 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
9607 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
9608 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:559609 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:129610 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:109611 GLfloat* dst = result->GetData();
9612 for (GLsizei ii = 0; ii < num_values; ++ii) {
9613 dst[ii] = (temp[ii] != 0);
9614 }
9615 } else {
[email protected]1b0a6752012-02-22 03:44:129616 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:109617 }
[email protected]f7b85372010-02-03 01:11:379618 }
9619 return error;
[email protected]96449d2c2009-11-25 00:01:329620}
9621
[email protected]f7a64ee2010-02-01 22:24:149622error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
vmiuracd108592014-09-08 14:36:349623 uint32 immediate_data_size,
9624 const void* cmd_data) {
9625 const gles2::cmds::GetShaderPrecisionFormat& c =
9626 *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259627 GLenum shader_type = static_cast<GLenum>(c.shadertype);
9628 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:359629 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:259630 Result* result = GetSharedMemoryAs<Result*>(
9631 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9632 if (!result) {
9633 return error::kOutOfBounds;
9634 }
[email protected]07d0cc82010-02-17 04:51:409635 // Check that the client initialized the result.
9636 if (result->success != 0) {
9637 return error::kInvalidArguments;
9638 }
[email protected]9438b012010-06-15 22:55:059639 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:519640 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539641 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:299642 return error::kNoError;
9643 }
[email protected]9438b012010-06-15 22:55:059644 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:519645 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:539646 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:299647 return error::kNoError;
9648 }
9649
9650 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:409651
[email protected]46c86752013-05-21 05:08:399652 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:409653 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:219654 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:409655
9656 result->min_range = range[0];
9657 result->max_range = range[1];
9658 result->precision = precision;
9659
[email protected]f7a64ee2010-02-01 22:24:149660 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329661}
9662
[email protected]f7a64ee2010-02-01 22:24:149663error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
vmiuracd108592014-09-08 14:36:349664 uint32 immediate_data_size,
9665 const void* cmd_data) {
9666 const gles2::cmds::GetAttachedShaders& c =
9667 *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data);
[email protected]0bfd9882010-02-05 23:02:259668 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:429669 GLuint program_id = static_cast<GLuint>(c.program);
9670 Program* program = GetProgramInfoNotShader(
9671 program_id, "glGetAttachedShaders");
9672 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259673 return error::kNoError;
9674 }
[email protected]ed9f9cd2013-02-27 21:12:359675 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:259676 uint32 max_count = Result::ComputeMaxResults(result_size);
9677 Result* result = GetSharedMemoryAs<Result*>(
9678 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
9679 if (!result) {
9680 return error::kOutOfBounds;
9681 }
[email protected]07d0cc82010-02-17 04:51:409682 // Check that the client initialized the result.
9683 if (result->size != 0) {
9684 return error::kInvalidArguments;
9685 }
[email protected]0bfd9882010-02-05 23:02:259686 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:039687 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:429688 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:259689 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:039690 if (!shader_manager()->GetClientId(result->GetData()[ii],
9691 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:259692 NOTREACHED();
9693 return error::kGenericError;
9694 }
9695 }
9696 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:149697 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329698}
9699
[email protected]f7a64ee2010-02-01 22:24:149700error::Error GLES2DecoderImpl::HandleGetActiveUniform(
vmiuracd108592014-09-08 14:36:349701 uint32 immediate_data_size,
9702 const void* cmd_data) {
9703 const gles2::cmds::GetActiveUniform& c =
9704 *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429705 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259706 GLuint index = c.index;
9707 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359708 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:259709 Result* result = GetSharedMemoryAs<Result*>(
9710 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9711 if (!result) {
9712 return error::kOutOfBounds;
9713 }
[email protected]07d0cc82010-02-17 04:51:409714 // Check that the client initialized the result.
9715 if (result->success != 0) {
9716 return error::kInvalidArguments;
9717 }
[email protected]df37b9932013-03-08 05:21:429718 Program* program = GetProgramInfoNotShader(
9719 program_id, "glGetActiveUniform");
9720 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259721 return error::kNoError;
9722 }
[email protected]ed9f9cd2013-02-27 21:12:359723 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:429724 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:259725 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:519726 LOCAL_SET_GL_ERROR(
9727 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259728 return error::kNoError;
9729 }
9730 result->success = 1; // true.
9731 result->size = uniform_info->size;
9732 result->type = uniform_info->type;
9733 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299734 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149735 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329736}
9737
zmoa2b555d2015-02-06 23:50:399738error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockiv(
9739 uint32 immediate_data_size, const void* cmd_data) {
9740 if (!unsafe_es3_apis_enabled())
9741 return error::kUnknownCommand;
9742 const gles2::cmds::GetActiveUniformBlockiv& c =
9743 *static_cast<const gles2::cmds::GetActiveUniformBlockiv*>(cmd_data);
9744 GLuint program_id = c.program;
9745 GLuint index = static_cast<GLuint>(c.index);
9746 GLenum pname = static_cast<GLenum>(c.pname);
9747 Program* program = GetProgramInfoNotShader(
zmo8fab00c2015-02-07 02:45:059748 program_id, "glGetActiveUniformBlockiv");
zmoa2b555d2015-02-06 23:50:399749 if (!program) {
9750 return error::kNoError;
9751 }
9752 GLuint service_id = program->service_id();
9753 GLint link_status = GL_FALSE;
9754 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
9755 if (link_status != GL_TRUE) {
9756 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9757 "glGetActiveActiveUniformBlockiv", "program not linked");
9758 return error::kNoError;
9759 }
9760 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetActiveUniformBlockiv");
9761 GLsizei num_values = 1;
9762 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) {
9763 GLint num = 0;
9764 glGetActiveUniformBlockiv(
9765 service_id, index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &num);
9766 GLenum error = glGetError();
9767 if (error != GL_NO_ERROR) {
9768 // Assume this will the same error if calling with pname.
9769 LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", "");
9770 return error::kNoError;
9771 }
9772 num_values = static_cast<GLsizei>(num);
9773 }
9774 typedef cmds::GetActiveUniformBlockiv::Result Result;
9775 Result* result = GetSharedMemoryAs<Result*>(
9776 c.params_shm_id, c.params_shm_offset, Result::ComputeSize(num_values));
9777 GLint* params = result ? result->GetData() : NULL;
9778 if (params == NULL) {
9779 return error::kOutOfBounds;
9780 }
9781 // Check that the client initialized the result.
9782 if (result->size != 0) {
9783 return error::kInvalidArguments;
9784 }
9785 glGetActiveUniformBlockiv(service_id, index, pname, params);
9786 GLenum error = glGetError();
9787 if (error == GL_NO_ERROR) {
9788 result->SetNumResults(num_values);
9789 } else {
9790 LOCAL_SET_GL_ERROR(error, "GetActiveUniformBlockiv", "");
9791 }
9792 return error::kNoError;
9793}
9794
zmo4a16ff992015-02-05 22:18:419795error::Error GLES2DecoderImpl::HandleGetActiveUniformBlockName(
9796 uint32 immediate_data_size, const void* cmd_data) {
9797 if (!unsafe_es3_apis_enabled())
9798 return error::kUnknownCommand;
9799 const gles2::cmds::GetActiveUniformBlockName& c =
9800 *static_cast<const gles2::cmds::GetActiveUniformBlockName*>(cmd_data);
9801 GLuint program_id = c.program;
9802 GLuint index = c.index;
9803 uint32 name_bucket_id = c.name_bucket_id;
9804 typedef cmds::GetActiveUniformBlockName::Result Result;
9805 Result* result = GetSharedMemoryAs<Result*>(
9806 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9807 if (!result) {
9808 return error::kOutOfBounds;
9809 }
9810 // Check that the client initialized the result.
9811 if (*result != 0) {
9812 return error::kInvalidArguments;
9813 }
9814 Program* program = GetProgramInfoNotShader(
9815 program_id, "glGetActiveUniformBlockName");
9816 if (!program) {
9817 return error::kNoError;
9818 }
9819 GLuint service_id = program->service_id();
9820 GLint link_status = GL_FALSE;
9821 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
9822 if (link_status != GL_TRUE) {
9823 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9824 "glGetActiveActiveUniformBlockName", "program not linked");
9825 return error::kNoError;
9826 }
9827 GLint max_length = 0;
9828 glGetProgramiv(
9829 service_id, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &max_length);
9830 // Increase one so &buffer[0] is always valid.
9831 GLsizei buf_size = static_cast<GLsizei>(max_length) + 1;
9832 std::vector<char> buffer(buf_size);
9833 GLsizei length = 0;
9834 glGetActiveUniformBlockName(
9835 service_id, index, buf_size, &length, &buffer[0]);
9836 if (length == 0) {
9837 *result = 0;
9838 return error::kNoError;
9839 }
9840 *result = 1;
9841 Bucket* bucket = CreateBucket(name_bucket_id);
9842 DCHECK_GT(buf_size, length);
9843 DCHECK_EQ(0, buffer[length]);
9844 bucket->SetFromString(&buffer[0]);
9845 return error::kNoError;
9846}
9847
vmiuracd108592014-09-08 14:36:349848error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size,
9849 const void* cmd_data) {
9850 const gles2::cmds::GetActiveAttrib& c =
9851 *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:429852 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:259853 GLuint index = c.index;
9854 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:359855 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:259856 Result* result = GetSharedMemoryAs<Result*>(
9857 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9858 if (!result) {
9859 return error::kOutOfBounds;
9860 }
[email protected]07d0cc82010-02-17 04:51:409861 // Check that the client initialized the result.
9862 if (result->success != 0) {
9863 return error::kInvalidArguments;
9864 }
[email protected]df37b9932013-03-08 05:21:429865 Program* program = GetProgramInfoNotShader(
9866 program_id, "glGetActiveAttrib");
9867 if (!program) {
[email protected]0bfd9882010-02-05 23:02:259868 return error::kNoError;
9869 }
[email protected]ed9f9cd2013-02-27 21:12:359870 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:429871 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:259872 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:519873 LOCAL_SET_GL_ERROR(
9874 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:259875 return error::kNoError;
9876 }
9877 result->success = 1; // true.
9878 result->size = attrib_info->size;
9879 result->type = attrib_info->type;
9880 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:299881 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:149882 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:329883}
9884
vmiuracd108592014-09-08 14:36:349885error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size,
9886 const void* cmd_data) {
[email protected]b273e432010-04-12 17:23:589887#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:519888 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:589889 return error::kNoError;
9890#else
9891 GLsizei n = static_cast<GLsizei>(c.n);
9892 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:519893 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:589894 return error::kNoError;
9895 }
9896 GLsizei length = static_cast<GLsizei>(c.length);
9897 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:519898 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:589899 return error::kNoError;
9900 }
9901 uint32 data_size;
9902 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
9903 return error::kOutOfBounds;
9904 }
9905 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
9906 c.shaders_shm_id, c.shaders_shm_offset, data_size);
9907 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
9908 const void* binary = GetSharedMemoryAs<const void*>(
9909 c.binary_shm_id, c.binary_shm_offset, length);
9910 if (shaders == NULL || binary == NULL) {
9911 return error::kOutOfBounds;
9912 }
[email protected]0782b14b2014-05-24 13:04:169913 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]b273e432010-04-12 17:23:589914 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:429915 Shader* shader = GetShader(shaders[ii]);
9916 if (!shader) {
[email protected]ab09b612013-03-11 22:11:519917 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:589918 return error::kNoError;
9919 }
[email protected]df37b9932013-03-08 05:21:429920 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:589921 }
9922 // TODO(gman): call glShaderBinary
9923 return error::kNoError;
9924#endif
9925}
9926
[email protected]6d792ee12013-05-15 00:40:569927void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:499928 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:089929
[email protected]64ace852011-05-19 21:49:499930 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:429931 // TRACE_EVENT for gpu tests:
9932 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:429933 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:429934 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
9935 "width", (is_offscreen ? offscreen_size_.width() :
9936 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:569937 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:499938 "offscreen", is_offscreen,
9939 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:159940 {
[email protected]a36ed4832014-04-24 16:40:279941 TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
[email protected]b2e92592014-01-10 15:47:159942 }
9943
dyenb547eff62015-01-17 00:14:569944 ScopedGPUTrace scoped_gpu_trace(gpu_tracer_.get(), kTraceDecoder,
9945 "gpu_toplevel", "SwapBuffer");
9946
[email protected]8f9b8dd2013-09-12 18:05:139947 bool is_tracing;
9948 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
9949 &is_tracing);
9950 if (is_tracing) {
9951 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
9952 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
9953 is_offscreen ? offscreen_size_ : surface_->GetSize());
9954 }
9955
[email protected]6217d392010-03-25 22:08:359956 // If offscreen then don't actually SwapBuffers to the display. Just copy
9957 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:499958 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:319959 TRACE_EVENT2("gpu", "Offscreen",
9960 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:539961 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
9962 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
9963 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
9964 // fix this.
[email protected]62e155e2012-10-23 22:43:159965 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:539966 offscreen_saved_frame_buffer_->Create();
9967 glFinish();
9968 }
9969
9970 // Allocate the offscreen saved color texture.
9971 DCHECK(offscreen_saved_color_format_);
9972 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:099973 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:539974
9975 offscreen_saved_frame_buffer_->AttachRenderTexture(
9976 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:059977 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
9978 if (offscreen_saved_frame_buffer_->CheckStatus() !=
9979 GL_FRAMEBUFFER_COMPLETE) {
9980 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
9981 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:569982 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
9983 return;
[email protected]f0cfe752013-01-14 01:09:059984 }
[email protected]1fb8c482011-08-31 01:01:539985
[email protected]f0cfe752013-01-14 01:09:059986 // Clear the offscreen color texture.
9987 // TODO(piman): Is this still necessary?
9988 {
9989 ScopedFrameBufferBinder binder(this,
9990 offscreen_saved_frame_buffer_->id());
9991 glClearColor(0, 0, 0, 0);
[email protected]454157e2014-05-03 02:49:459992 state_.SetDeviceColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
9993 state_.SetDeviceCapabilityState(GL_SCISSOR_TEST, false);
[email protected]f0cfe752013-01-14 01:09:059994 glClear(GL_COLOR_BUFFER_BIT);
9995 RestoreClearState();
9996 }
[email protected]1fb8c482011-08-31 01:01:539997 }
9998
9999 UpdateParentTextureInfo();
10000 }
10001
[email protected]f0cfe752013-01-14 01:09:0510002 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:5610003 return;
[email protected]ab09b612013-03-11 22:11:5110004 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010005 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:3510006
[email protected]34ff8b0c2010-10-01 20:06:0210007 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:1310008 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:2710009 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:4810010 } else {
[email protected]069944672012-04-25 20:52:2310011 ScopedFrameBufferBinder binder(this,
10012 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:1310013
[email protected]069944672012-04-25 20:52:2310014 if (offscreen_target_buffer_preserved_) {
10015 // Copy the target frame buffer to the saved offscreen texture.
10016 offscreen_saved_color_texture_->Copy(
10017 offscreen_saved_color_texture_->size(),
10018 offscreen_saved_color_format_);
10019 } else {
10020 // Flip the textures in the parent context via the texture manager.
10021 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:4910022 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:2310023 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:5610024
[email protected]069944672012-04-25 20:52:2310025 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
10026 offscreen_target_frame_buffer_->AttachRenderTexture(
10027 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:4810028 }
[email protected]069944672012-04-25 20:52:2310029
10030 // Ensure the side effects of the copy are visible to the parent
10031 // context. There is no need to do this for ANGLE because it uses a
10032 // single D3D device for all contexts.
zmo68fcdc62014-12-05 21:51:4910033 if (!feature_info_->gl_version_info().is_angle)
[email protected]069944672012-04-25 20:52:2310034 glFlush();
[email protected]0c8c9d22010-06-25 17:36:3910035 }
[email protected]6217d392010-03-25 22:08:3510036 } else {
[email protected]f62a5ab2011-05-23 20:34:1510037 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:0110038 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:5610039 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:0110040 }
[email protected]6217d392010-03-25 22:08:3510041 }
vmiura8266ca72014-09-09 21:37:0010042
10043 // This may be a slow command. Exit command processing to allow for
10044 // context preemption and GPU watchdog checks.
10045 ExitCommandProcessingEarly();
[email protected]6217d392010-03-25 22:08:3510046}
10047
bajones2345c1f2014-12-09 04:45:5110048void GLES2DecoderImpl::DoSwapInterval(int interval)
10049{
10050 context_->SetSwapInterval(interval);
10051}
10052
[email protected]d4239852011-08-12 04:51:2210053error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
vmiuracd108592014-09-08 14:36:3410054 uint32 immediate_data_size,
10055 const void* cmd_data) {
10056 const gles2::cmds::EnableFeatureCHROMIUM& c =
10057 *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data);
[email protected]b1d2dcb2010-05-17 19:24:1810058 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:2810059 if (!bucket || bucket->size() == 0) {
10060 return error::kInvalidArguments;
10061 }
[email protected]ed9f9cd2013-02-27 21:12:3510062 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:1810063 Result* result = GetSharedMemoryAs<Result*>(
10064 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10065 if (!result) {
10066 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:1010067 }
[email protected]b1d2dcb2010-05-17 19:24:1810068 // Check that the client initialized the result.
10069 if (*result != 0) {
10070 return error::kInvalidArguments;
10071 }
10072 std::string feature_str;
10073 if (!bucket->GetAsString(&feature_str)) {
10074 return error::kInvalidArguments;
10075 }
10076
10077 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:2210078 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:1810079 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:2210080 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
penghuang0140c182015-01-12 23:20:1210081 buffer_manager()->set_allow_fixed_attribs(true);
[email protected]8fbedc02010-11-18 18:43:4010082 // TODO(gman): decide how to remove the need for this const_cast.
10083 // I could make validators_ non const but that seems bad as this is the only
10084 // place it is needed. I could make some special friend class of validators
10085 // just to allow this to set them. That seems silly. I could refactor this
10086 // code to use the extension mechanism or the initialization attributes to
10087 // turn this feature on. Given that the only real point of this is to make
10088 // the conformance tests pass and given that there is lots of real work that
10089 // needs to be done it seems like refactoring for one to one of those
10090 // methods is a very low priority.
10091 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:0410092 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
10093 force_webgl_glsl_validation_ = true;
10094 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:1810095 } else {
10096 return error::kNoError;
10097 }
10098
10099 *result = 1; // true.
10100 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:1010101}
10102
[email protected]c2f8c8402010-12-06 18:07:2410103error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
10104 uint32 immediate_data_size,
vmiuracd108592014-09-08 14:36:3410105 const void* cmd_data) {
10106 const gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
10107 *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
10108 cmd_data);
[email protected]c2f8c8402010-12-06 18:07:2410109 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:3510110 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:1910111 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:2410112 bucket->SetFromString(info->extensions().c_str());
10113 return error::kNoError;
10114}
10115
10116error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
vmiuracd108592014-09-08 14:36:3410117 uint32 immediate_data_size,
10118 const void* cmd_data) {
10119 const gles2::cmds::RequestExtensionCHROMIUM& c =
10120 *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data);
[email protected]c2f8c8402010-12-06 18:07:2410121 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:2810122 if (!bucket || bucket->size() == 0) {
10123 return error::kInvalidArguments;
10124 }
[email protected]c2f8c8402010-12-06 18:07:2410125 std::string feature_str;
10126 if (!bucket->GetAsString(&feature_str)) {
10127 return error::kInvalidArguments;
10128 }
10129
[email protected]4b7eba92013-01-08 02:23:5610130 bool desire_webgl_glsl_validation =
10131 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
10132 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:4910133 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:1310134 bool desire_draw_buffers = false;
[email protected]93c2fd82014-04-16 02:46:0610135 bool desire_shader_texture_lod = false;
[email protected]4b7eba92013-01-08 02:23:5610136 if (force_webgl_glsl_validation_) {
10137 desire_standard_derivatives =
10138 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:4910139 desire_frag_depth =
10140 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:1310141 desire_draw_buffers =
10142 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]93c2fd82014-04-16 02:46:0610143 desire_shader_texture_lod =
10144 feature_str.find("GL_EXT_shader_texture_lod") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:0410145 }
10146
[email protected]4b7eba92013-01-08 02:23:5610147 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:4910148 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:1310149 desire_frag_depth != frag_depth_explicitly_enabled_ ||
10150 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:4910151 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
10152 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
10153 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:1310154 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]93c2fd82014-04-16 02:46:0610155 shader_texture_lod_explicitly_enabled_ |= desire_shader_texture_lod;
[email protected]c2f8c8402010-12-06 18:07:2410156 InitializeShaderTranslator();
10157 }
10158
[email protected]302ce6d2011-07-07 23:28:1110159 UpdateCapabilities();
10160
[email protected]c2f8c8402010-12-06 18:07:2410161 return error::kNoError;
10162}
10163
[email protected]2318d342011-07-11 22:27:4210164error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
vmiuracd108592014-09-08 14:36:3410165 uint32 immediate_data_size,
10166 const void* cmd_data) {
10167 const gles2::cmds::GetProgramInfoCHROMIUM& c =
10168 *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data);
[email protected]df37b9932013-03-08 05:21:4210169 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:4210170 uint32 bucket_id = c.bucket_id;
10171 Bucket* bucket = CreateBucket(bucket_id);
10172 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:4210173 Program* program = NULL;
10174 program = GetProgram(program_id);
10175 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:4610176 return error::kNoError;
[email protected]2318d342011-07-11 22:27:4210177 }
[email protected]df37b9932013-03-08 05:21:4210178 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:4210179 return error::kNoError;
10180}
10181
zmo4a16ff992015-02-05 22:18:4110182error::Error GLES2DecoderImpl::HandleGetUniformBlocksCHROMIUM(
10183 uint32 immediate_data_size, const void* cmd_data) {
10184 if (!unsafe_es3_apis_enabled())
10185 return error::kUnknownCommand;
10186 const gles2::cmds::GetUniformBlocksCHROMIUM& c =
10187 *static_cast<const gles2::cmds::GetUniformBlocksCHROMIUM*>(cmd_data);
10188 GLuint program_id = static_cast<GLuint>(c.program);
10189 uint32 bucket_id = c.bucket_id;
10190 Bucket* bucket = CreateBucket(bucket_id);
10191 bucket->SetSize(sizeof(UniformBlocksHeader)); // in case we fail.
10192 Program* program = NULL;
10193 program = GetProgram(program_id);
10194 if (!program || !program->IsValid()) {
10195 return error::kNoError;
10196 }
10197 program->GetUniformBlocks(bucket);
10198 return error::kNoError;
10199}
10200
zmo10842492015-02-12 00:44:1610201error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVarying(
10202 uint32 immediate_data_size,
10203 const void* cmd_data) {
10204 if (!unsafe_es3_apis_enabled())
10205 return error::kUnknownCommand;
10206 const gles2::cmds::GetTransformFeedbackVarying& c =
10207 *static_cast<const gles2::cmds::GetTransformFeedbackVarying*>(cmd_data);
10208 GLuint program_id = c.program;
10209 GLuint index = c.index;
10210 uint32 name_bucket_id = c.name_bucket_id;
10211 typedef cmds::GetTransformFeedbackVarying::Result Result;
10212 Result* result = GetSharedMemoryAs<Result*>(
10213 c.result_shm_id, c.result_shm_offset, sizeof(*result));
10214 if (!result) {
10215 return error::kOutOfBounds;
10216 }
10217 // Check that the client initialized the result.
10218 if (result->success != 0) {
10219 return error::kInvalidArguments;
10220 }
10221 Program* program = GetProgramInfoNotShader(
10222 program_id, "glGetTransformFeedbackVarying");
10223 if (!program) {
10224 return error::kNoError;
10225 }
10226 GLuint service_id = program->service_id();
10227 GLint link_status = GL_FALSE;
10228 glGetProgramiv(service_id, GL_LINK_STATUS, &link_status);
10229 if (link_status != GL_TRUE) {
10230 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10231 "glGetTransformFeedbackVarying", "program not linked");
10232 return error::kNoError;
10233 }
10234 GLint max_length = 0;
10235 glGetProgramiv(
10236 service_id, GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &max_length);
10237 max_length = std::max(1, max_length);
10238 std::vector<char> buffer(max_length);
10239 GLsizei length = 0;
10240 GLsizei size = 0;
10241 GLenum type = 0;
10242 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("GetTransformFeedbackVarying");
10243 glGetTransformFeedbackVarying(
10244 service_id, index, max_length, &length, &size, &type, &buffer[0]);
10245 GLenum error = glGetError();
10246 if (error != GL_NO_ERROR) {
10247 LOCAL_SET_GL_ERROR(error, "glGetTransformFeedbackVarying", "");
10248 return error::kNoError;
10249 }
10250 result->success = 1; // true.
10251 result->size = static_cast<int32_t>(size);
10252 result->type = static_cast<uint32_t>(type);
10253 Bucket* bucket = CreateBucket(name_bucket_id);
10254 DCHECK(length >= 0 && length < max_length);
10255 buffer[length] = '\0'; // Just to be safe.
10256 bucket->SetFromString(&buffer[0]);
10257 return error::kNoError;
10258}
10259
10260error::Error GLES2DecoderImpl::HandleGetTransformFeedbackVaryingsCHROMIUM(
10261 uint32 immediate_data_size, const void* cmd_data) {
10262 if (!unsafe_es3_apis_enabled())
10263 return error::kUnknownCommand;
10264 const gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM& c =
10265 *static_cast<const gles2::cmds::GetTransformFeedbackVaryingsCHROMIUM*>(
10266 cmd_data);
10267 GLuint program_id = static_cast<GLuint>(c.program);
10268 uint32 bucket_id = c.bucket_id;
10269 Bucket* bucket = CreateBucket(bucket_id);
10270 bucket->SetSize(sizeof(TransformFeedbackVaryingsHeader)); // in case we fail.
10271 Program* program = NULL;
10272 program = GetProgram(program_id);
10273 if (!program || !program->IsValid()) {
10274 return error::kNoError;
10275 }
10276 program->GetTransformFeedbackVaryings(bucket);
10277 return error::kNoError;
10278}
10279
[email protected]38d139d2011-07-14 00:38:4310280error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
10281 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:4310282 case GL_NO_ERROR:
10283 // TODO(kbr): improve the precision of the error code in this case.
10284 // Consider delegating to context for error code if MakeCurrent fails.
10285 return error::kUnknown;
10286 case GL_GUILTY_CONTEXT_RESET_ARB:
10287 return error::kGuilty;
10288 case GL_INNOCENT_CONTEXT_RESET_ARB:
10289 return error::kInnocent;
10290 case GL_UNKNOWN_CONTEXT_RESET_ARB:
10291 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:4310292 }
10293
10294 NOTREACHED();
10295 return error::kUnknown;
10296}
10297
jbauman7a059312014-10-16 19:30:5410298void GLES2DecoderImpl::MaybeExitOnContextLost() {
10299 // Some D3D drivers cannot recover from device lost in the GPU process
10300 // sandbox. Allow a new GPU process to launch.
10301 if (workarounds().exit_on_context_lost) {
10302 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
10303 << " a D3D device in the Chrome GPU process sandbox.";
10304#if defined(OS_WIN)
10305 base::win::SetShouldCrashOnProcessDetach(false);
10306#endif
10307 exit(0);
10308 }
10309}
10310
[email protected]38d139d2011-07-14 00:38:4310311bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:0910312 if (reset_status_ != GL_NO_ERROR) {
jbauman7a059312014-10-16 19:30:5410313 MaybeExitOnContextLost();
[email protected]c4485aad62012-12-17 10:19:0910314 return true;
10315 }
dongseong.hwange1cb2aa2015-02-11 09:33:3310316 if (IsRobustnessSupported()) {
10317 GLenum status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:4310318 if (status != GL_NO_ERROR) {
10319 // The graphics card was reset. Signal a lost context to the application.
10320 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:2210321 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:4310322 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:0910323 << " context lost via ARB/EXT_robustness. Reset status = "
10324 << GLES2Util::GetStringEnum(status);
jbauman7a059312014-10-16 19:30:5410325 MaybeExitOnContextLost();
[email protected]38d139d2011-07-14 00:38:4310326 return true;
10327 }
10328 }
10329 return false;
10330}
10331
[email protected]93a7d98f2013-07-11 00:04:2210332bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
10333 return WasContextLost() && reset_by_robustness_extension_;
10334}
10335
[email protected]c4485aad62012-12-17 10:19:0910336void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
10337 // Only loses the context once.
10338 if (reset_status_ != GL_NO_ERROR) {
10339 return;
10340 }
10341
oetuaho37cc50e2014-10-31 11:19:2010342 if (workarounds().use_virtualized_gl_contexts) {
10343 // If the context is virtual, the real context being guilty does not ensure
10344 // that the virtual context is guilty.
10345 if (reset_status == GL_GUILTY_CONTEXT_RESET_ARB) {
10346 reset_status = GL_UNKNOWN_CONTEXT_RESET_ARB;
10347 }
10348 } else if (reset_status == GL_UNKNOWN_CONTEXT_RESET_ARB &&
dongseong.hwange1cb2aa2015-02-11 09:33:3310349 IsRobustnessSupported()) {
oetuaho37cc50e2014-10-31 11:19:2010350 // If the reason for the call was a GL error, we can try to determine the
10351 // reset status more accurately.
10352 GLenum driver_status = glGetGraphicsResetStatusARB();
10353 if (driver_status == GL_GUILTY_CONTEXT_RESET_ARB ||
10354 driver_status == GL_INNOCENT_CONTEXT_RESET_ARB) {
10355 reset_status = driver_status;
10356 }
10357 }
10358
[email protected]c4485aad62012-12-17 10:19:0910359 // Marks this context as lost.
10360 reset_status_ = reset_status;
10361 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:0910362}
10363
[email protected]b096d032013-03-08 03:08:0110364error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:3410365 uint32 immediate_data_size,
10366 const void* cmd_data) {
[email protected]b096d032013-03-08 03:08:0110367 return error::kUnknownCommand;
10368}
10369
[email protected]840a7e462013-02-27 01:29:5110370error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
vmiuracd108592014-09-08 14:36:3410371 uint32 immediate_data_size,
10372 const void* cmd_data) {
10373 const gles2::cmds::WaitSyncPointCHROMIUM& c =
10374 *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
sievers173a20d2014-10-22 18:19:3210375 uint32 sync_point = c.sync_point;
[email protected]840a7e462013-02-27 01:29:5110376 if (wait_sync_point_callback_.is_null())
10377 return error::kNoError;
10378
sievers173a20d2014-10-22 18:19:3210379 return wait_sync_point_callback_.Run(sync_point) ?
[email protected]840a7e462013-02-27 01:29:5110380 error::kNoError : error::kDeferCommandUntilLater;
10381}
10382
[email protected]5dfc457b2013-12-13 11:13:0710383error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
vmiuracd108592014-09-08 14:36:3410384 uint32 immediate_data_size,
10385 const void* cmd_data) {
[email protected]5dfc457b2013-12-13 11:13:0710386 if (surface_->DeferDraws())
10387 return error::kDeferCommandUntilLater;
10388 if (!surface_->SetBackbufferAllocation(false))
10389 return error::kLostContext;
10390 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
10391 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
10392 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
10393 return error::kNoError;
10394}
10395
[email protected]882ba1e22012-03-08 19:02:5310396bool GLES2DecoderImpl::GenQueriesEXTHelper(
10397 GLsizei n, const GLuint* client_ids) {
10398 for (GLsizei ii = 0; ii < n; ++ii) {
10399 if (query_manager_->GetQuery(client_ids[ii])) {
10400 return false;
10401 }
10402 }
[email protected]4eea7e62014-04-22 21:14:4310403 query_manager_->GenQueries(n, client_ids);
[email protected]882ba1e22012-03-08 19:02:5310404 return true;
10405}
10406
10407void GLES2DecoderImpl::DeleteQueriesEXTHelper(
10408 GLsizei n, const GLuint* client_ids) {
10409 for (GLsizei ii = 0; ii < n; ++ii) {
10410 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
10411 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:1310412 ContextState::QueryMap::iterator it =
10413 state_.current_queries.find(query->target());
10414 if (it != state_.current_queries.end())
10415 state_.current_queries.erase(it);
10416
[email protected]c45f1972012-03-14 07:27:3610417 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:5310418 }
[email protected]4eea7e62014-04-22 21:14:4310419 query_manager_->RemoveQuery(client_ids[ii]);
[email protected]882ba1e22012-03-08 19:02:5310420 }
10421}
10422
revemancc241eb2014-11-11 03:30:3710423bool GLES2DecoderImpl::ProcessPendingQueries(bool did_finish) {
[email protected]22e3f552012-03-13 01:54:1910424 if (query_manager_.get() == NULL) {
10425 return false;
10426 }
revemancc241eb2014-11-11 03:30:3710427 if (!query_manager_->ProcessPendingQueries(did_finish)) {
[email protected]22e3f552012-03-13 01:54:1910428 current_decoder_error_ = error::kOutOfBounds;
10429 }
10430 return query_manager_->HavePendingQueries();
10431}
10432
[email protected]5a36dc132013-07-23 23:17:5510433// Note that if there are no pending readpixels right now,
10434// this function will call the callback immediately.
10435void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
10436 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
10437 pending_readpixel_fences_.back()->callbacks.push_back(callback);
10438 } else {
10439 callback.Run();
10440 }
10441}
10442
10443void GLES2DecoderImpl::ProcessPendingReadPixels() {
10444 while (!pending_readpixel_fences_.empty() &&
10445 pending_readpixel_fences_.front()->fence->HasCompleted()) {
10446 std::vector<base::Closure> callbacks =
10447 pending_readpixel_fences_.front()->callbacks;
10448 pending_readpixel_fences_.pop();
10449 for (size_t i = 0; i < callbacks.size(); i++) {
10450 callbacks[i].Run();
10451 }
10452 }
10453}
10454
[email protected]2b1767cf2013-03-16 09:25:0510455bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5510456 return !pending_readpixel_fences_.empty() ||
10457 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510458}
10459
10460void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:5510461 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:4810462 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:0510463 return;
[email protected]b68b100752013-06-05 08:34:4810464 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:0510465 ProcessFinishedAsyncTransfers();
10466}
10467
vmiuracd108592014-09-08 14:36:3410468error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size,
10469 const void* cmd_data) {
10470 const gles2::cmds::BeginQueryEXT& c =
10471 *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310472 GLenum target = static_cast<GLenum>(c.target);
10473 GLuint client_id = static_cast<GLuint>(c.id);
10474 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
10475 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
10476
[email protected]c45f1972012-03-14 07:27:3610477 switch (target) {
10478 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:5510479 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:3110480 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
10481 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:0010482 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:3610483 break;
[email protected]6a25ae422014-04-17 23:48:2710484 case GL_COMMANDS_COMPLETED_CHROMIUM:
10485 if (!features().chromium_sync_query) {
10486 LOCAL_SET_GL_ERROR(
10487 GL_INVALID_OPERATION, "glBeginQueryEXT",
10488 "not enabled for commands completed queries");
10489 return error::kNoError;
10490 }
10491 break;
[email protected]c45f1972012-03-14 07:27:3610492 default:
[email protected]62e155e2012-10-23 22:43:1510493 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:5110494 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:0010495 GL_INVALID_OPERATION, "glBeginQueryEXT",
10496 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:3610497 return error::kNoError;
10498 }
10499 break;
[email protected]882ba1e22012-03-08 19:02:5310500 }
10501
[email protected]8ebd46c2014-01-08 12:06:1310502 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110503 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310504 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:5310505 return error::kNoError;
10506 }
10507
10508 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:5110509 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:5310510 return error::kNoError;
10511 }
10512
10513 QueryManager::Query* query = query_manager_->GetQuery(client_id);
10514 if (!query) {
[email protected]4eea7e62014-04-22 21:14:4310515 if (!query_manager_->IsValidQuery(client_id)) {
10516 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10517 "glBeginQueryEXT",
10518 "id not made by glGenQueriesEXT");
10519 return error::kNoError;
10520 }
[email protected]c45f1972012-03-14 07:27:3610521 query = query_manager_->CreateQuery(
10522 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:5310523 }
10524
[email protected]c45f1972012-03-14 07:27:3610525 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110526 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310527 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:5310528 return error::kNoError;
10529 } else if (query->shm_id() != sync_shm_id ||
10530 query->shm_offset() != sync_shm_offset) {
10531 DLOG(ERROR) << "Shared memory used by query not the same as before";
10532 return error::kInvalidArguments;
10533 }
10534
[email protected]c45f1972012-03-14 07:27:3610535 if (!query_manager_->BeginQuery(query)) {
10536 return error::kOutOfBounds;
10537 }
[email protected]882ba1e22012-03-08 19:02:5310538
[email protected]8ebd46c2014-01-08 12:06:1310539 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:5310540 return error::kNoError;
10541}
10542
vmiuracd108592014-09-08 14:36:3410543error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size,
10544 const void* cmd_data) {
10545 const gles2::cmds::EndQueryEXT& c =
10546 *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data);
[email protected]882ba1e22012-03-08 19:02:5310547 GLenum target = static_cast<GLenum>(c.target);
10548 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:1310549 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:5310550
[email protected]8ebd46c2014-01-08 12:06:1310551 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:5110552 LOCAL_SET_GL_ERROR(
10553 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:5310554 return error::kNoError;
10555 }
[email protected]882ba1e22012-03-08 19:02:5310556
[email protected]8ebd46c2014-01-08 12:06:1310557 QueryManager::Query* query = it->second.get();
10558 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:3610559 return error::kOutOfBounds;
10560 }
10561
[email protected]fe8d73c2013-02-16 22:37:3210562 query_manager_->ProcessPendingTransferQueries();
10563
[email protected]8ebd46c2014-01-08 12:06:1310564 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:5310565 return error::kNoError;
10566}
10567
[email protected]944b62f32012-09-27 02:20:4610568bool GLES2DecoderImpl::GenVertexArraysOESHelper(
10569 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610570 for (GLsizei ii = 0; ii < n; ++ii) {
10571 if (GetVertexAttribManager(client_ids[ii])) {
10572 return false;
10573 }
10574 }
[email protected]ab4fd7282012-10-12 16:25:5710575
[email protected]62e155e2012-10-23 22:43:1510576 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710577 // Emulated VAO
10578 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810579 CreateVertexAttribManager(client_ids[ii], 0, true);
[email protected]ab4fd7282012-10-12 16:25:5710580 }
10581 } else {
[email protected]40d90a22013-04-09 03:39:5510582 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:5710583
10584 glGenVertexArraysOES(n, service_ids.get());
10585 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]da364812014-05-09 21:39:4810586 CreateVertexAttribManager(client_ids[ii], service_ids[ii], true);
[email protected]ab4fd7282012-10-12 16:25:5710587 }
[email protected]944b62f32012-09-27 02:20:4610588 }
[email protected]ab4fd7282012-10-12 16:25:5710589
[email protected]944b62f32012-09-27 02:20:4610590 return true;
10591}
10592
10593void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
10594 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:4610595 for (GLsizei ii = 0; ii < n; ++ii) {
10596 VertexAttribManager* vao =
10597 GetVertexAttribManager(client_ids[ii]);
10598 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:1110599 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]242c9822014-04-15 21:36:1110600 DoBindVertexArrayOES(0);
[email protected]944b62f32012-09-27 02:20:4610601 }
10602 RemoveVertexAttribManager(client_ids[ii]);
10603 }
10604 }
10605}
10606
10607void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610608 VertexAttribManager* vao = NULL;
[email protected]944b62f32012-09-27 02:20:4610609 if (client_id != 0) {
10610 vao = GetVertexAttribManager(client_id);
10611 if (!vao) {
10612 // Unlike most Bind* methods, the spec explicitly states that VertexArray
10613 // only allows names that have been previously generated. As such, we do
10614 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:5110615 LOCAL_SET_GL_ERROR(
10616 GL_INVALID_OPERATION,
10617 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:4610618 current_decoder_error_ = error::kNoError;
10619 return;
[email protected]944b62f32012-09-27 02:20:4610620 }
[email protected]944b62f32012-09-27 02:20:4610621 } else {
[email protected]81f20a622014-04-18 01:54:5210622 vao = state_.default_vertex_attrib_manager.get();
[email protected]944b62f32012-09-27 02:20:4610623 }
10624
[email protected]ab4fd7282012-10-12 16:25:5710625 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:1110626 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:2410627 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:1510628 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:5710629 EmulateVertexArrayState();
10630 } else {
[email protected]da364812014-05-09 21:39:4810631 GLuint service_id = vao->service_id();
[email protected]ab4fd7282012-10-12 16:25:5710632 glBindVertexArrayOES(service_id);
10633 }
10634 }
10635}
10636
10637// Used when OES_vertex_array_object isn't natively supported
10638void GLES2DecoderImpl::EmulateVertexArrayState() {
10639 // Setup the Vertex attribute state
10640 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
[email protected]3fc38e22014-05-30 00:13:2310641 RestoreStateForAttrib(vv, true);
[email protected]ab4fd7282012-10-12 16:25:5710642 }
10643
10644 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:2110645 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:2410646 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:5710647 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
10648 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:4610649}
10650
10651bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:4610652 const VertexAttribManager* vao =
10653 GetVertexAttribManager(client_id);
10654 return vao && vao->IsValid() && !vao->IsDeleted();
10655}
10656
[email protected]e51bdf32011-11-23 22:21:4610657#if defined(OS_MACOSX)
10658void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
10659 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
10660 texture_id);
10661 if (it != texture_to_io_surface_map_.end()) {
10662 // Found a previous IOSurface bound to this texture; release it.
[email protected]c3a6b4a2014-06-04 09:25:5310663 IOSurfaceRef surface = it->second;
[email protected]e51bdf32011-11-23 22:21:4610664 CFRelease(surface);
10665 texture_to_io_surface_map_.erase(it);
10666 }
10667}
10668#endif
10669
10670void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
10671 GLenum target, GLsizei width, GLsizei height,
10672 GLuint io_surface_id, GLuint plane) {
10673#if defined(OS_MACOSX)
10674 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:5110675 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310676 GL_INVALID_OPERATION,
10677 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:4610678 return;
10679 }
10680
[email protected]e51bdf32011-11-23 22:21:4610681 if (target != GL_TEXTURE_RECTANGLE_ARB) {
10682 // This might be supported in the future, and if we could require
10683 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
10684 // could delete a lot of code. For now, perform strict validation so we
10685 // know what's going on.
[email protected]ab09b612013-03-11 22:11:5110686 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610687 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310688 "glTexImageIOSurface2DCHROMIUM",
10689 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:4610690 return;
10691 }
10692
[email protected]09d50362012-10-18 20:54:3710693 // Default target might be conceptually valid, but disallow it to avoid
10694 // accidents.
[email protected]c986af502013-08-14 01:04:4410695 TextureRef* texture_ref =
10696 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910697 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110698 LOCAL_SET_GL_ERROR(
10699 GL_INVALID_OPERATION,
10700 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:4610701 return;
10702 }
[email protected]e51bdf32011-11-23 22:21:4610703
10704 // Look up the new IOSurface. Note that because of asynchrony
10705 // between processes this might fail; during live resizing the
10706 // plugin process might allocate and release an IOSurface before
10707 // this process gets a chance to look it up. Hold on to any old
10708 // IOSurface in this case.
[email protected]c3a6b4a2014-06-04 09:25:5310709 IOSurfaceRef surface = IOSurfaceLookup(io_surface_id);
[email protected]e51bdf32011-11-23 22:21:4610710 if (!surface) {
[email protected]ab09b612013-03-11 22:11:5110711 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310712 GL_INVALID_OPERATION,
10713 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:4610714 return;
10715 }
10716
10717 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:4910718 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:4610719
10720 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
10721 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:4910722 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:4610723
10724 CGLContextObj context =
10725 static_cast<CGLContextObj>(context_->GetHandle());
10726
[email protected]c3a6b4a2014-06-04 09:25:5310727 CGLError err = CGLTexImageIOSurface2D(
[email protected]e51bdf32011-11-23 22:21:4610728 context,
10729 target,
10730 GL_RGBA,
10731 width,
10732 height,
10733 GL_BGRA,
10734 GL_UNSIGNED_INT_8_8_8_8_REV,
10735 surface,
10736 plane);
10737
10738 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:5110739 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:4610740 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310741 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:4610742 return;
10743 }
10744
10745 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910746 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:4610747 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
10748
10749#else
[email protected]ab09b612013-03-11 22:11:5110750 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:4310751 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:4610752#endif
10753}
10754
[email protected]97dc7cbe2011-12-06 17:26:1710755static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
10756 switch (internalformat) {
10757 case GL_RGB565:
10758 return GL_RGB;
10759 case GL_RGBA4:
10760 return GL_RGBA;
10761 case GL_RGB5_A1:
10762 return GL_RGBA;
10763 case GL_RGB8_OES:
10764 return GL_RGB;
10765 case GL_RGBA8_OES:
10766 return GL_RGBA;
10767 case GL_LUMINANCE8_ALPHA8_EXT:
10768 return GL_LUMINANCE_ALPHA;
10769 case GL_LUMINANCE8_EXT:
10770 return GL_LUMINANCE;
10771 case GL_ALPHA8_EXT:
10772 return GL_ALPHA;
10773 case GL_RGBA32F_EXT:
10774 return GL_RGBA;
10775 case GL_RGB32F_EXT:
10776 return GL_RGB;
10777 case GL_ALPHA32F_EXT:
10778 return GL_ALPHA;
10779 case GL_LUMINANCE32F_EXT:
10780 return GL_LUMINANCE;
10781 case GL_LUMINANCE_ALPHA32F_EXT:
10782 return GL_LUMINANCE_ALPHA;
10783 case GL_RGBA16F_EXT:
10784 return GL_RGBA;
10785 case GL_RGB16F_EXT:
10786 return GL_RGB;
10787 case GL_ALPHA16F_EXT:
10788 return GL_ALPHA;
10789 case GL_LUMINANCE16F_EXT:
10790 return GL_LUMINANCE;
10791 case GL_LUMINANCE_ALPHA16F_EXT:
10792 return GL_LUMINANCE_ALPHA;
10793 case GL_BGRA8_EXT:
10794 return GL_BGRA_EXT;
bajones2a2ea232014-10-13 21:38:5910795 case GL_SRGB8_ALPHA8_EXT:
10796 return GL_SRGB_ALPHA_EXT;
[email protected]97dc7cbe2011-12-06 17:26:1710797 default:
10798 return GL_NONE;
10799 }
10800}
10801
[email protected]43410e92012-04-20 17:06:2810802void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:0310803 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:5410804 GLenum internal_format, GLenum dest_type) {
[email protected]1e24dc7f2014-04-14 02:40:0810805 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCopyTextureCHROMIUM");
10806
[email protected]370eaf12013-05-18 09:19:4910807 TextureRef* dest_texture_ref = GetTexture(dest_id);
10808 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:2810809
[email protected]370eaf12013-05-18 09:19:4910810 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110811 LOCAL_SET_GL_ERROR(
10812 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:2810813 return;
10814 }
10815
10816 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110817 LOCAL_SET_GL_ERROR(
10818 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:2810819 return;
10820 }
10821
[email protected]370eaf12013-05-18 09:19:4910822 Texture* source_texture = source_texture_ref->texture();
10823 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710824 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:2510825 (source_texture->target() != GL_TEXTURE_2D &&
[email protected]041d463f2014-04-30 05:38:3410826 source_texture->target() != GL_TEXTURE_RECTANGLE_ARB &&
10827 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]3ecc1052013-09-26 08:59:0010828 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10829 "glCopyTextureCHROMIUM",
10830 "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:0310831 return;
10832 }
10833
[email protected]43410e92012-04-20 17:06:2810834 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:2810835
[email protected]3e0dfd72014-02-21 06:28:4110836 gfx::GLImage* image =
10837 source_texture->GetLevelImage(source_texture->target(), 0);
10838 if (image) {
[email protected]7bffe9e12014-01-27 23:02:5510839 gfx::Size size = image->GetSize();
[email protected]377976552013-05-14 23:32:5610840 source_width = size.width();
10841 source_height = size.height();
10842 if (source_width <= 0 || source_height <= 0) {
10843 LOCAL_SET_GL_ERROR(
10844 GL_INVALID_VALUE,
[email protected]7bffe9e12014-01-27 23:02:5510845 "glCopyTextureChromium", "invalid image size");
[email protected]377976552013-05-14 23:32:5610846 return;
10847 }
[email protected]3ecc1052013-09-26 08:59:0010848 } else {
10849 if (!source_texture->GetLevelSize(
10850 source_texture->target(), 0, &source_width, &source_height)) {
10851 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
10852 "glCopyTextureChromium",
10853 "source texture has no level 0");
10854 return;
10855 }
10856
10857 // Check that this type of texture is allowed.
10858 if (!texture_manager()->ValidForTarget(
10859 source_texture->target(), level, source_width, source_height, 1)) {
10860 LOCAL_SET_GL_ERROR(
10861 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
10862 return;
10863 }
[email protected]377976552013-05-14 23:32:5610864 }
10865
[email protected]04b5b37d2014-02-07 02:11:5110866 // Clear the source texture if necessary.
10867 if (!texture_manager()->ClearTextureLevel(
10868 this, source_texture_ref, source_texture->target(), 0)) {
10869 LOCAL_SET_GL_ERROR(
10870 GL_OUT_OF_MEMORY, "glCopyTextureCHROMIUM", "dimensions too big");
10871 return;
10872 }
10873
[email protected]a6e3d282014-08-22 22:20:4410874 GLenum source_type = 0;
10875 GLenum source_internal_format = 0;
10876 source_texture->GetLevelType(
10877 source_texture->target(), 0, &source_type, &source_internal_format);
10878
10879 // The destination format should be GL_RGB, or GL_RGBA. GL_ALPHA,
10880 // GL_LUMINANCE, and GL_LUMINANCE_ALPHA are not supported because they are not
10881 // renderable on some platforms.
reveman6b0fbe42014-09-04 00:55:0310882 bool valid_dest_format = internal_format == GL_RGB ||
10883 internal_format == GL_RGBA ||
10884 internal_format == GL_BGRA_EXT;
[email protected]a6e3d282014-08-22 22:20:4410885 bool valid_source_format = source_internal_format == GL_ALPHA ||
10886 source_internal_format == GL_RGB ||
10887 source_internal_format == GL_RGBA ||
10888 source_internal_format == GL_LUMINANCE ||
10889 source_internal_format == GL_LUMINANCE_ALPHA ||
10890 source_internal_format == GL_BGRA_EXT;
10891 if (!valid_source_format || !valid_dest_format) {
10892 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10893 "glCopyTextureCHROMIUM",
10894 "invalid internal format");
10895 return;
10896 }
10897
[email protected]cf6b8f62012-05-25 21:43:3710898 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
10899 // needed because it takes 10s of milliseconds to initialize.
10900 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:5110901 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:3710902 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:2710903 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:3710904 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:5110905 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:3710906 return;
10907 }
10908
[email protected]efc87712014-07-09 00:22:4710909 GLenum dest_type_previous = dest_type;
10910 GLenum dest_internal_format = internal_format;
[email protected]02965c22013-03-09 02:40:0710911 bool dest_level_defined = dest_texture->GetLevelSize(
10912 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:2810913
[email protected]0a1e9ad2012-05-04 21:13:0310914 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:5410915 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:0710916 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:0310917 }
10918
10919 // Resize the destination texture to the dimensions of the source texture.
10920 if (!dest_level_defined || dest_width != source_width ||
10921 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:5410922 dest_internal_format != internal_format ||
10923 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:2810924 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:5110925 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:0710926 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:3810927 glTexImage2D(
[email protected]43410e92012-04-20 17:06:2810928 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:0310929 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:5110930 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:0310931 if (error != GL_NO_ERROR) {
[email protected]2b10c02d2014-01-29 16:43:0210932 RestoreCurrentTextureBindings(&state_, GL_TEXTURE_2D);
[email protected]43410e92012-04-20 17:06:2810933 return;
[email protected]0a1e9ad2012-05-04 21:13:0310934 }
[email protected]43410e92012-04-20 17:06:2810935
10936 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910937 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:0310938 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:2510939 } else {
[email protected]02965c22013-03-09 02:40:0710940 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:4910941 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:2810942 }
10943
[email protected]00c2cf92014-03-14 00:08:3710944 ScopedModifyPixels modify(dest_texture_ref);
[email protected]91c94eb2013-10-22 10:32:5410945
revemance8fbe82014-09-05 02:19:5210946 // Try using GLImage::CopyTexImage when possible.
10947 bool unpack_premultiply_alpha_change =
10948 unpack_premultiply_alpha_ ^ unpack_unpremultiply_alpha_;
10949 if (image && !unpack_flip_y_ && !unpack_premultiply_alpha_change && !level) {
10950 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
10951 if (image->CopyTexImage(GL_TEXTURE_2D))
10952 return;
10953 }
10954
10955 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
10956
[email protected]5394a4102013-04-18 05:41:3710957 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
10958 // before presenting.
10959 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
10960 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
10961 // instead of using default matrix crbug.com/226218.
10962 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
10963 0.0f, 1.0f, 0.0f, 0.0f,
10964 0.0f, 0.0f, 1.0f, 0.0f,
10965 0.0f, 0.0f, 0.0f, 1.0f};
10966 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
10967 this,
10968 source_texture->target(),
[email protected]5394a4102013-04-18 05:41:3710969 source_texture->service_id(),
[email protected]90f7d30d2014-08-13 02:51:5710970 dest_texture->service_id(),
10971 level,
10972 source_width,
10973 source_height,
[email protected]5394a4102013-04-18 05:41:3710974 unpack_flip_y_,
10975 unpack_premultiply_alpha_,
10976 unpack_unpremultiply_alpha_,
10977 default_matrix);
10978 } else {
[email protected]90f7d30d2014-08-13 02:51:5710979 copy_texture_CHROMIUM_->DoCopyTexture(this,
10980 source_texture->target(),
10981 source_texture->service_id(),
10982 source_internal_format,
10983 dest_texture->service_id(),
10984 level,
10985 internal_format,
10986 source_width,
10987 source_height,
10988 unpack_flip_y_,
10989 unpack_premultiply_alpha_,
10990 unpack_unpremultiply_alpha_);
[email protected]5394a4102013-04-18 05:41:3710991 }
[email protected]91c94eb2013-10-22 10:32:5410992
10993 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:2810994}
10995
[email protected]97dc7cbe2011-12-06 17:26:1710996static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
10997 switch (internalformat) {
10998 case GL_RGB565:
10999 return GL_UNSIGNED_SHORT_5_6_5;
11000 case GL_RGBA4:
11001 return GL_UNSIGNED_SHORT_4_4_4_4;
11002 case GL_RGB5_A1:
11003 return GL_UNSIGNED_SHORT_5_5_5_1;
11004 case GL_RGB8_OES:
11005 return GL_UNSIGNED_BYTE;
11006 case GL_RGBA8_OES:
11007 return GL_UNSIGNED_BYTE;
11008 case GL_LUMINANCE8_ALPHA8_EXT:
11009 return GL_UNSIGNED_BYTE;
11010 case GL_LUMINANCE8_EXT:
11011 return GL_UNSIGNED_BYTE;
11012 case GL_ALPHA8_EXT:
11013 return GL_UNSIGNED_BYTE;
11014 case GL_RGBA32F_EXT:
11015 return GL_FLOAT;
11016 case GL_RGB32F_EXT:
11017 return GL_FLOAT;
11018 case GL_ALPHA32F_EXT:
11019 return GL_FLOAT;
11020 case GL_LUMINANCE32F_EXT:
11021 return GL_FLOAT;
11022 case GL_LUMINANCE_ALPHA32F_EXT:
11023 return GL_FLOAT;
11024 case GL_RGBA16F_EXT:
11025 return GL_HALF_FLOAT_OES;
11026 case GL_RGB16F_EXT:
11027 return GL_HALF_FLOAT_OES;
11028 case GL_ALPHA16F_EXT:
11029 return GL_HALF_FLOAT_OES;
11030 case GL_LUMINANCE16F_EXT:
11031 return GL_HALF_FLOAT_OES;
11032 case GL_LUMINANCE_ALPHA16F_EXT:
11033 return GL_HALF_FLOAT_OES;
11034 case GL_BGRA8_EXT:
11035 return GL_UNSIGNED_BYTE;
11036 default:
11037 return GL_NONE;
11038 }
11039}
11040
11041void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4411042 GLenum target,
11043 GLint levels,
11044 GLenum internal_format,
11045 GLsizei width,
11046 GLsizei height) {
[email protected]67f929422014-05-17 15:33:1311047 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT",
11048 "width", width, "height", height);
[email protected]80eb6b52012-01-19 00:14:4111049 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0011050 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5111051 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4311052 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1711053 return;
11054 }
[email protected]c986af502013-08-14 01:04:4411055 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11056 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911057 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111058 LOCAL_SET_GL_ERROR(
11059 GL_INVALID_OPERATION,
11060 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1711061 return;
11062 }
[email protected]370eaf12013-05-18 09:19:4911063 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0711064 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4411065 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1711066 }
[email protected]02965c22013-03-09 02:40:0711067 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5111068 LOCAL_SET_GL_ERROR(
11069 GL_INVALID_OPERATION,
11070 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1711071 return;
11072 }
[email protected]7989c9e2013-01-23 06:39:2611073
11074 GLenum format = ExtractFormatFromStorageFormat(internal_format);
11075 GLenum type = ExtractTypeFromStorageFormat(internal_format);
11076
11077 {
11078 GLsizei level_width = width;
11079 GLsizei level_height = height;
11080 uint32 estimated_size = 0;
11081 for (int ii = 0; ii < levels; ++ii) {
11082 uint32 level_size = 0;
11083 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4211084 level_width, level_height, 1, format, type, state_.unpack_alignment,
[email protected]7989c9e2013-01-23 06:39:2611085 &estimated_size, NULL, NULL) ||
11086 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5111087 LOCAL_SET_GL_ERROR(
11088 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2611089 return;
11090 }
11091 level_width = std::max(1, level_width >> 1);
11092 level_height = std::max(1, level_height >> 1);
11093 }
11094 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5111095 LOCAL_SET_GL_ERROR(
11096 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2611097 return;
11098 }
11099 }
11100
[email protected]ab09b612013-03-11 22:11:5111101 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3811102 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5111103 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1711104 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1511105 GLsizei level_width = width;
11106 GLsizei level_height = height;
11107 for (int ii = 0; ii < levels; ++ii) {
11108 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911109 texture_ref, target, ii, format,
11110 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:1511111 level_width = std::max(1, level_width >> 1);
11112 level_height = std::max(1, level_height >> 1);
11113 }
[email protected]02965c22013-03-09 02:40:0711114 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1711115 }
[email protected]97dc7cbe2011-12-06 17:26:1711116}
[email protected]e51bdf32011-11-23 22:21:4611117
[email protected]78b514b2012-05-01 21:50:5911118error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
vmiuracd108592014-09-08 14:36:3411119 uint32 immediate_data_size,
11120 const void* cmd_data) {
[email protected]baed42c2013-10-01 05:06:3511121 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5911122}
11123
11124void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3711125 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0211126 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3211127 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3711128 "mailbox[0]", static_cast<unsigned char>(data[0]));
11129
[email protected]43f253da2014-06-10 17:51:2211130 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11131 &state_, target);
11132 ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data);
11133}
11134
11135void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id,
11136 GLenum target, const GLbyte* data) {
11137 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM",
11138 "context", logger_.GetLogPrefix(),
11139 "mailbox[0]", static_cast<unsigned char>(data[0]));
11140
11141 ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id),
11142 target, data);
11143}
11144
11145void GLES2DecoderImpl::ProduceTextureRef(std::string func_name,
11146 TextureRef* texture_ref, GLenum target, const GLbyte* data) {
[email protected]64ba52f2014-02-15 14:22:3711147 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
[email protected]43f253da2014-06-10 17:51:2211148 DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a "
[email protected]64ba52f2014-02-15 14:22:3711149 "mailbox that was not generated by "
11150 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0211151
[email protected]370eaf12013-05-18 09:19:4911152 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111153 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2211154 GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5911155 return;
11156 }
11157
[email protected]62e65f02013-05-29 22:28:1011158 Texture* produced = texture_manager()->Produce(texture_ref);
11159 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5111160 LOCAL_SET_GL_ERROR(
[email protected]43f253da2014-06-10 17:51:2211161 GL_INVALID_OPERATION, func_name.c_str(), "invalid texture");
11162 return;
11163 }
11164
11165 if (produced->target() != target) {
11166 LOCAL_SET_GL_ERROR(
11167 GL_INVALID_OPERATION, func_name.c_str(), "invalid target");
[email protected]78b514b2012-05-01 21:50:5911168 return;
11169 }
11170
sievers8b373ec52014-10-24 23:04:0611171 group_->mailbox_manager()->ProduceTexture(mailbox, produced);
[email protected]78b514b2012-05-01 21:50:5911172}
11173
11174void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
[email protected]64ba52f2014-02-15 14:22:3711175 const GLbyte* data) {
[email protected]987b9c02013-03-23 00:58:0211176 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3211177 "context", logger_.GetLogPrefix(),
[email protected]64ba52f2014-02-15 14:22:3711178 "mailbox[0]", static_cast<unsigned char>(data[0]));
11179 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
11180 DLOG_IF(ERROR, !mailbox.Verify()) << "ConsumeTextureCHROMIUM was passed a "
11181 "mailbox that was not generated by "
11182 "GenMailboxCHROMIUM.";
[email protected]987b9c02013-03-23 00:58:0211183
[email protected]62e65f02013-05-29 22:28:1011184 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4411185 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1111186 if (!texture_ref.get()) {
11187 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11188 "glConsumeTextureCHROMIUM",
11189 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5911190 return;
11191 }
[email protected]62e65f02013-05-29 22:28:1011192 GLuint client_id = texture_ref->client_id();
11193 if (!client_id) {
11194 LOCAL_SET_GL_ERROR(
11195 GL_INVALID_OPERATION,
11196 "glConsumeTextureCHROMIUM", "unknown texture for target");
11197 return;
11198 }
sievers8b373ec52014-10-24 23:04:0611199 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]62e65f02013-05-29 22:28:1011200 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5111201 LOCAL_SET_GL_ERROR(
11202 GL_INVALID_OPERATION,
11203 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5911204 return;
11205 }
[email protected]62e65f02013-05-29 22:28:1011206 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5111207 LOCAL_SET_GL_ERROR(
11208 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1011209 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5911210 return;
11211 }
[email protected]62e65f02013-05-29 22:28:1011212
11213 DeleteTexturesHelper(1, &client_id);
11214 texture_ref = texture_manager()->Consume(client_id, texture);
11215 glBindTexture(target, texture_ref->service_id());
11216
11217 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
11218 unit.bind_target = target;
11219 switch (target) {
11220 case GL_TEXTURE_2D:
11221 unit.bound_texture_2d = texture_ref;
11222 break;
11223 case GL_TEXTURE_CUBE_MAP:
11224 unit.bound_texture_cube_map = texture_ref;
11225 break;
11226 case GL_TEXTURE_EXTERNAL_OES:
11227 unit.bound_texture_external_oes = texture_ref;
11228 break;
11229 case GL_TEXTURE_RECTANGLE_ARB:
11230 unit.bound_texture_rectangle_arb = texture_ref;
11231 break;
11232 default:
11233 NOTREACHED(); // Validation should prevent us getting here.
11234 break;
11235 }
[email protected]78b514b2012-05-01 21:50:5911236}
11237
[email protected]43f253da2014-06-10 17:51:2211238error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
11239 uint32_t immediate_data_size,
vmiuracd108592014-09-08 14:36:3411240 const void* cmd_data) {
11241 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c =
11242 *static_cast<
11243 const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>(
11244 cmd_data);
[email protected]43f253da2014-06-10 17:51:2211245 GLenum target = static_cast<GLenum>(c.target);
11246 uint32_t data_size;
11247 if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
11248 return error::kOutOfBounds;
11249 }
11250 if (data_size > immediate_data_size) {
11251 return error::kOutOfBounds;
11252 }
11253 const GLbyte* mailbox =
11254 GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size);
11255 if (!validators_->texture_bind_target.IsValid(target)) {
11256 LOCAL_SET_GL_ERROR_INVALID_ENUM(
11257 "glCreateAndConsumeTextureCHROMIUM", target, "target");
11258 return error::kNoError;
11259 }
11260 if (mailbox == NULL) {
11261 return error::kOutOfBounds;
11262 }
11263 uint32_t client_id = c.client_id;
11264 DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id);
11265 return error::kNoError;
11266}
11267
11268void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target,
11269 const GLbyte* data, GLuint client_id) {
11270 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM",
11271 "context", logger_.GetLogPrefix(),
11272 "mailbox[0]", static_cast<unsigned char>(data[0]));
11273 const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data);
11274 DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was "
11275 "passed a mailbox that was not "
11276 "generated by GenMailboxCHROMIUM.";
11277
11278 TextureRef* texture_ref = GetTexture(client_id);
11279 if (texture_ref) {
11280 LOCAL_SET_GL_ERROR(
11281 GL_INVALID_OPERATION,
11282 "glCreateAndConsumeTextureCHROMIUM", "client id already in use");
11283 return;
11284 }
sievers8b373ec52014-10-24 23:04:0611285 Texture* texture = group_->mailbox_manager()->ConsumeTexture(mailbox);
[email protected]43f253da2014-06-10 17:51:2211286 if (!texture) {
11287 LOCAL_SET_GL_ERROR(
11288 GL_INVALID_OPERATION,
11289 "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name");
11290 return;
11291 }
11292 if (texture->target() != target) {
11293 LOCAL_SET_GL_ERROR(
11294 GL_INVALID_OPERATION,
11295 "glCreateAndConsumeTextureCHROMIUM", "invalid target");
11296 return;
11297 }
11298
[email protected]43f253da2014-06-10 17:51:2211299 texture_ref = texture_manager()->Consume(client_id, texture);
11300}
11301
orglofchcad5a6742014-11-07 19:51:1211302bool GLES2DecoderImpl::DoIsValuebufferCHROMIUM(GLuint client_id) {
11303 const Valuebuffer* valuebuffer = GetValuebuffer(client_id);
11304 return valuebuffer && valuebuffer->IsValid();
11305}
11306
11307void GLES2DecoderImpl::DoBindValueBufferCHROMIUM(GLenum target,
11308 GLuint client_id) {
11309 Valuebuffer* valuebuffer = NULL;
11310 if (client_id != 0) {
11311 valuebuffer = GetValuebuffer(client_id);
11312 if (!valuebuffer) {
11313 if (!group_->bind_generates_resource()) {
11314 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBindValuebufferCHROMIUM",
11315 "id not generated by glBindValuebufferCHROMIUM");
11316 return;
11317 }
11318
11319 // It's a new id so make a valuebuffer for it.
11320 CreateValuebuffer(client_id);
11321 valuebuffer = GetValuebuffer(client_id);
11322 }
11323 valuebuffer->MarkAsValid();
11324 }
11325 state_.bound_valuebuffer = valuebuffer;
11326}
11327
11328void GLES2DecoderImpl::DoSubscribeValueCHROMIUM(GLenum target,
11329 GLenum subscription) {
11330 if (!CheckCurrentValuebuffer("glSubscribeValueCHROMIUM")) {
11331 return;
11332 }
11333 state_.bound_valuebuffer.get()->AddSubscription(subscription);
11334}
11335
11336void GLES2DecoderImpl::DoPopulateSubscribedValuesCHROMIUM(GLenum target) {
11337 if (!CheckCurrentValuebuffer("glPopulateSubscribedValuesCHROMIUM")) {
11338 return;
11339 }
11340 valuebuffer_manager()->UpdateValuebufferState(state_.bound_valuebuffer.get());
11341}
11342
11343void GLES2DecoderImpl::DoUniformValueBufferCHROMIUM(GLint location,
11344 GLenum target,
11345 GLenum subscription) {
11346 if (!CheckCurrentValuebufferForSubscription(
11347 subscription, "glPopulateSubscribedValuesCHROMIUM")) {
11348 return;
11349 }
11350 if (!CheckSubscriptionTarget(location, subscription,
11351 "glPopulateSubscribedValuesCHROMIUM")) {
11352 return;
11353 }
11354 const ValueState* state =
11355 state_.bound_valuebuffer.get()->GetState(subscription);
11356 if (state) {
11357 switch (subscription) {
11358 case GL_MOUSE_POSITION_CHROMIUM:
11359 DoUniform2iv(location, 1, state->int_value);
11360 break;
11361 default:
11362 NOTREACHED() << "Unhandled uniform subscription target "
11363 << subscription;
11364 break;
11365 }
11366 }
11367}
11368
[email protected]d2a0e1a2012-08-12 02:25:0111369void GLES2DecoderImpl::DoInsertEventMarkerEXT(
11370 GLsizei length, const GLchar* marker) {
11371 if (!marker) {
11372 marker = "";
11373 }
11374 debug_marker_manager_.SetMarker(
11375 length ? std::string(marker, length) : std::string(marker));
11376}
11377
11378void GLES2DecoderImpl::DoPushGroupMarkerEXT(
11379 GLsizei length, const GLchar* marker) {
11380 if (!marker) {
11381 marker = "";
11382 }
[email protected]cac16542014-01-15 17:53:5111383 std::string name = length ? std::string(marker, length) : std::string(marker);
11384 debug_marker_manager_.PushGroup(name);
dyen4bb43282015-01-08 01:09:5611385 gpu_tracer_->Begin(TRACE_DISABLED_BY_DEFAULT("gpu_group_marker"), name,
11386 kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0111387}
11388
11389void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
11390 debug_marker_manager_.PopGroup();
dyen4bb43282015-01-08 01:09:5611391 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0111392}
11393
[email protected]09d50362012-10-18 20:54:3711394void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
11395 GLenum target, GLint image_id) {
11396 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3711397
[email protected]bc26e8d2014-01-29 00:40:3011398 if (target == GL_TEXTURE_CUBE_MAP) {
11399 LOCAL_SET_GL_ERROR(
11400 GL_INVALID_ENUM,
11401 "glBindTexImage2DCHROMIUM", "invalid target");
11402 return;
11403 }
11404
[email protected]09d50362012-10-18 20:54:3711405 // Default target might be conceptually valid, but disallow it to avoid
11406 // accidents.
[email protected]c986af502013-08-14 01:04:4411407 TextureRef* texture_ref =
11408 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4911409 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111410 LOCAL_SET_GL_ERROR(
11411 GL_INVALID_OPERATION,
11412 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3711413 return;
11414 }
11415
11416 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
11417 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5111418 LOCAL_SET_GL_ERROR(
11419 GL_INVALID_OPERATION,
11420 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3711421 return;
11422 }
11423
[email protected]b8160812013-04-09 00:41:0411424 {
11425 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3011426 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2611427 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0411428 LOCAL_SET_GL_ERROR(
11429 GL_INVALID_OPERATION,
11430 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
11431 return;
11432 }
[email protected]09d50362012-10-18 20:54:3711433 }
11434
11435 gfx::Size size = gl_image->GetSize();
11436 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911437 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3711438 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4911439 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3711440}
11441
11442void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
11443 GLenum target, GLint image_id) {
11444 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3711445
11446 // Default target might be conceptually valid, but disallow it to avoid
11447 // accidents.
[email protected]c986af502013-08-14 01:04:4411448 TextureRef* texture_ref =
11449 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4911450 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111451 LOCAL_SET_GL_ERROR(
11452 GL_INVALID_OPERATION,
11453 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3711454 return;
11455 }
11456
11457 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
11458 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5111459 LOCAL_SET_GL_ERROR(
11460 GL_INVALID_OPERATION,
11461 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3711462 return;
11463 }
11464
11465 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4911466 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3711467 return;
11468
[email protected]b8160812013-04-09 00:41:0411469 {
11470 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3011471 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2611472 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0411473 }
[email protected]09d50362012-10-18 20:54:3711474
11475 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4911476 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3711477 GL_RGBA, GL_UNSIGNED_BYTE, false);
11478}
[email protected]d2a0e1a2012-08-12 02:25:0111479
[email protected]94307712012-11-16 23:26:1111480error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
vmiuracd108592014-09-08 14:36:3411481 uint32 immediate_data_size,
11482 const void* cmd_data) {
11483 const gles2::cmds::TraceBeginCHROMIUM& c =
11484 *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
dyencb86f2f2014-12-09 18:35:4111485 Bucket* category_bucket = GetBucket(c.category_bucket_id);
11486 Bucket* name_bucket = GetBucket(c.name_bucket_id);
11487 if (!category_bucket || category_bucket->size() == 0 ||
11488 !name_bucket || name_bucket->size() == 0) {
[email protected]94307712012-11-16 23:26:1111489 return error::kInvalidArguments;
11490 }
dyencb86f2f2014-12-09 18:35:4111491
11492 std::string category_name;
11493 std::string trace_name;
11494 if (!category_bucket->GetAsString(&category_name) ||
11495 !name_bucket->GetAsString(&trace_name)) {
[email protected]94307712012-11-16 23:26:1111496 return error::kInvalidArguments;
11497 }
dyencb86f2f2014-12-09 18:35:4111498
dyencb86f2f2014-12-09 18:35:4111499 if (!gpu_tracer_->Begin(category_name, trace_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5111500 LOCAL_SET_GL_ERROR(
11501 GL_INVALID_OPERATION,
11502 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1411503 return error::kNoError;
11504 }
[email protected]94307712012-11-16 23:26:1111505 return error::kNoError;
11506}
11507
11508void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
dyen4bb43282015-01-08 01:09:5611509 if (!gpu_tracer_->End(kTraceCHROMIUM)) {
11510 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11511 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1111512 return;
11513 }
[email protected]94307712012-11-16 23:26:1111514}
11515
[email protected]2f143d482013-03-14 18:04:4911516void GLES2DecoderImpl::DoDrawBuffersEXT(
11517 GLsizei count, const GLenum* bufs) {
11518 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
11519 LOCAL_SET_GL_ERROR(
11520 GL_INVALID_VALUE,
11521 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
11522 return;
11523 }
11524
11525 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
11526 if (framebuffer) {
11527 for (GLsizei i = 0; i < count; ++i) {
11528 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
11529 bufs[i] != GL_NONE) {
11530 LOCAL_SET_GL_ERROR(
11531 GL_INVALID_OPERATION,
11532 "glDrawBuffersEXT",
11533 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
11534 return;
11535 }
11536 }
11537 glDrawBuffersARB(count, bufs);
11538 framebuffer->SetDrawBuffers(count, bufs);
11539 } else { // backbuffer
11540 if (count > 1 ||
11541 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
11542 LOCAL_SET_GL_ERROR(
11543 GL_INVALID_OPERATION,
11544 "glDrawBuffersEXT",
11545 "more than one buffer or bufs not GL_NONE or GL_BACK");
11546 return;
11547 }
11548 GLenum mapped_buf = bufs[0];
11549 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
11550 bufs[0] == GL_BACK) {
11551 mapped_buf = GL_COLOR_ATTACHMENT0;
11552 }
11553 glDrawBuffersARB(count, &mapped_buf);
11554 group_->set_draw_buffer(bufs[0]);
11555 }
11556}
11557
[email protected]a6a09f852014-05-23 13:05:0311558void GLES2DecoderImpl::DoLoseContextCHROMIUM(GLenum current, GLenum other) {
11559 group_->LoseContexts(other);
11560 reset_status_ = current;
11561 current_decoder_error_ = error::kLostContext;
11562}
11563
kkinnunen337d59632014-08-26 10:19:5711564void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
11565 const GLfloat* matrix) {
11566 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
11567 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
11568 if (!features().chromium_path_rendering) {
11569 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11570 "glMatrixLoadfCHROMIUM",
11571 "function not available");
11572 return;
11573 }
11574
11575 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
11576 ? state_.projection_matrix
11577 : state_.modelview_matrix;
11578 memcpy(target_matrix, matrix, sizeof(GLfloat) * 16);
11579 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
11580 // since the values of the _NV and _CHROMIUM tokens match.
11581 glMatrixLoadfEXT(matrix_mode, matrix);
11582}
11583
11584void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
11585 DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
11586 matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
11587
11588 if (!features().chromium_path_rendering) {
11589 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
11590 "glMatrixLoadIdentityCHROMIUM",
11591 "function not available");
11592 return;
11593 }
11594
11595 static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
11596 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
11597 0.0f, 0.0f, 0.0f, 1.0f};
11598
11599 GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
11600 ? state_.projection_matrix
11601 : state_.modelview_matrix;
11602 memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
11603 // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
11604 // since the values of the _NV and _CHROMIUM tokens match.
11605 glMatrixLoadIdentityEXT(matrix_mode);
11606}
11607
[email protected]32145a92012-12-17 09:01:5911608bool GLES2DecoderImpl::ValidateAsyncTransfer(
11609 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4711610 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5911611 GLenum target,
11612 GLint level,
11613 const void * data) {
11614 // We only support async uploads to 2D textures for now.
11615 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5111616 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5911617 return false;
11618 }
11619 // We only support uploads to level zero for now.
11620 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5111621 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5911622 return false;
11623 }
11624 // A transfer buffer must be bound, even for asyncTexImage2D.
11625 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5111626 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5911627 return false;
11628 }
11629 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4711630 if (!texture_ref ||
11631 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5111632 LOCAL_SET_GL_ERROR(
11633 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911634 function_name, "transfer already in progress");
11635 return false;
11636 }
11637 return true;
11638}
11639
[email protected]e3c4a9ab2014-03-31 09:07:0211640base::Closure GLES2DecoderImpl::AsyncUploadTokenCompletionClosure(
11641 uint32 async_upload_token,
11642 uint32 sync_data_shm_id,
11643 uint32 sync_data_shm_offset) {
11644 scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_data_shm_id);
Daniel Cheng3d7ce9f2014-08-26 00:26:2511645 if (!buffer.get() ||
11646 !buffer->GetDataAddress(sync_data_shm_offset, sizeof(AsyncUploadSync)))
[email protected]e3c4a9ab2014-03-31 09:07:0211647 return base::Closure();
11648
11649 AsyncMemoryParams mem_params(buffer,
11650 sync_data_shm_offset,
11651 sizeof(AsyncUploadSync));
11652
11653 scoped_refptr<AsyncUploadTokenCompletionObserver> observer(
11654 new AsyncUploadTokenCompletionObserver(async_upload_token));
11655
11656 return base::Bind(
11657 &AsyncPixelTransferManager::AsyncNotifyCompletion,
11658 base::Unretained(GetAsyncPixelTransferManager()),
11659 mem_params,
11660 observer);
11661}
11662
[email protected]69023942012-11-30 19:57:1611663error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411664 uint32 immediate_data_size,
11665 const void* cmd_data) {
11666 const gles2::cmds::AsyncTexImage2DCHROMIUM& c =
11667 *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611668 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611669 GLenum target = static_cast<GLenum>(c.target);
11670 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4411671 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1611672 GLsizei width = static_cast<GLsizei>(c.width);
11673 GLsizei height = static_cast<GLsizei>(c.height);
11674 GLint border = static_cast<GLint>(c.border);
11675 GLenum format = static_cast<GLenum>(c.format);
11676 GLenum type = static_cast<GLenum>(c.type);
11677 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
11678 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
11679 uint32 pixels_size;
[email protected]e3c4a9ab2014-03-31 09:07:0211680 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11681 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11682 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11683
11684 base::ScopedClosureRunner scoped_completion_callback;
11685 if (async_upload_token) {
11686 base::Closure completion_closure =
11687 AsyncUploadTokenCompletionClosure(async_upload_token,
11688 sync_data_shm_id,
11689 sync_data_shm_offset);
11690 if (completion_closure.is_null())
11691 return error::kInvalidArguments;
11692
11693 scoped_completion_callback.Reset(completion_closure);
11694 }
[email protected]32145a92012-12-17 09:01:5911695
11696 // TODO(epenner): Move this and copies of this memory validation
11697 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1611698 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4211699 width, height, 1, format, type, state_.unpack_alignment, &pixels_size,
11700 NULL, NULL)) {
[email protected]69023942012-11-30 19:57:1611701 return error::kOutOfBounds;
11702 }
11703 const void* pixels = NULL;
11704 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
11705 pixels = GetSharedMemoryAs<const void*>(
11706 pixels_shm_id, pixels_shm_offset, pixels_size);
11707 if (!pixels) {
11708 return error::kOutOfBounds;
11709 }
11710 }
11711
[email protected]c986af502013-08-14 01:04:4411712 TextureManager::DoTextImage2DArguments args = {
11713 target, level, internal_format, width, height, border, format, type,
11714 pixels, pixels_size};
11715 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5911716 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4411717 if (!texture_manager()->ValidateTexImage2D(
11718 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5911719 return error::kNoError;
11720 }
11721
11722 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4911723 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911724 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711725 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911726 return error::kNoError;
11727
11728 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0711729 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5111730 LOCAL_SET_GL_ERROR(
11731 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5911732 "glAsyncTexImage2DCHROMIUM", "already defined");
11733 return error::kNoError;
11734 }
11735
[email protected]7989c9e2013-01-23 06:39:2611736 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5111737 LOCAL_SET_GL_ERROR(
11738 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2611739 return error::kNoError;
11740 }
11741
[email protected]5b3a8e02013-03-13 05:36:4411742 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3811743 AsyncTexImage2DParams tex_params = {
11744 target, level, static_cast<GLenum>(internal_format),
11745 width, height, border, format, type};
[email protected]c8021e02014-03-27 06:10:1211746 AsyncMemoryParams mem_params(
11747 GetSharedMemoryBuffer(c.pixels_shm_id), c.pixels_shm_offset, pixels_size);
[email protected]32145a92012-12-17 09:01:5911748
[email protected]5b3a8e02013-03-13 05:36:4411749 // Set up the async state if needed, and make the texture
11750 // immutable so the async state stays valid. The level info
11751 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1811752 AsyncPixelTransferDelegate* delegate =
11753 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
11754 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4411755 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5911756
[email protected]896425e2013-06-12 17:27:1811757 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4411758 tex_params,
11759 mem_params,
11760 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4911761 // The callback is only invoked if the transfer delegate still
11762 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4411763 // ownership that both of these pointers are valid.
11764 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4911765 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4411766 tex_params));
[email protected]f598f422012-12-07 08:30:0311767 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611768}
11769
11770error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411771 uint32 immediate_data_size,
11772 const void* cmd_data) {
11773 const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c =
11774 *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data);
[email protected]69023942012-11-30 19:57:1611775 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1611776 GLenum target = static_cast<GLenum>(c.target);
11777 GLint level = static_cast<GLint>(c.level);
11778 GLint xoffset = static_cast<GLint>(c.xoffset);
11779 GLint yoffset = static_cast<GLint>(c.yoffset);
11780 GLsizei width = static_cast<GLsizei>(c.width);
11781 GLsizei height = static_cast<GLsizei>(c.height);
11782 GLenum format = static_cast<GLenum>(c.format);
11783 GLenum type = static_cast<GLenum>(c.type);
[email protected]e3c4a9ab2014-03-31 09:07:0211784 uint32 async_upload_token = static_cast<uint32>(c.async_upload_token);
11785 uint32 sync_data_shm_id = static_cast<uint32>(c.sync_data_shm_id);
11786 uint32 sync_data_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
11787
11788 base::ScopedClosureRunner scoped_completion_callback;
11789 if (async_upload_token) {
11790 base::Closure completion_closure =
11791 AsyncUploadTokenCompletionClosure(async_upload_token,
11792 sync_data_shm_id,
11793 sync_data_shm_offset);
11794 if (completion_closure.is_null())
11795 return error::kInvalidArguments;
11796
11797 scoped_completion_callback.Reset(completion_closure);
11798 }
[email protected]32145a92012-12-17 09:01:5911799
11800 // TODO(epenner): Move this and copies of this memory validation
11801 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1611802 uint32 data_size;
11803 if (!GLES2Util::ComputeImageDataSizes(
zmobcadd6592015-01-08 20:13:4211804 width, height, 1, format, type, state_.unpack_alignment, &data_size,
[email protected]69023942012-11-30 19:57:1611805 NULL, NULL)) {
11806 return error::kOutOfBounds;
11807 }
11808 const void* pixels = GetSharedMemoryAs<const void*>(
11809 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5911810
11811 // All the normal glTexSubImage2D validation.
11812 error::Error error = error::kNoError;
11813 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
11814 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
11815 return error;
[email protected]69023942012-11-30 19:57:1611816 }
11817
[email protected]32145a92012-12-17 09:01:5911818 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4411819 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11820 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911821 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5911822 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4711823 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5911824 return error::kNoError;
11825
11826 // Guarantee async textures are always 'cleared' as follows:
11827 // - AsyncTexImage2D can not redefine an existing texture
11828 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
11829 // - AsyncTexSubImage2D clears synchronously if not already cleared.
11830 // - Textures become immutable after an async call.
11831 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0711832 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4911833 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
11834 target, level)) {
[email protected]ab09b612013-03-11 22:11:5111835 LOCAL_SET_GL_ERROR(
11836 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2511837 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5911838 return error::kNoError;
11839 }
11840 }
11841
[email protected]5b3a8e02013-03-13 05:36:4411842 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0311843 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5911844 width, height, format, type};
[email protected]c8021e02014-03-27 06:10:1211845 AsyncMemoryParams mem_params(
11846 GetSharedMemoryBuffer(c.data_shm_id), c.data_shm_offset, data_size);
[email protected]896425e2013-06-12 17:27:1811847 AsyncPixelTransferDelegate* delegate =
11848 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11849 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4411850 // TODO(epenner): We may want to enforce exclusive use
11851 // of async APIs in which case this should become an error,
11852 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0311853 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4411854 0, 0, 0, 0, 0, 0};
11855 texture->GetLevelSize(target, level, &define_params.width,
11856 &define_params.height);
11857 texture->GetLevelType(target, level, &define_params.type,
11858 &define_params.internal_format);
11859 // Set up the async state if needed, and make the texture
11860 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1811861 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4711862 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4411863 texture->SetImmutable(true);
11864 }
11865
[email protected]896425e2013-06-12 17:27:1811866 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5911867 return error::kNoError;
[email protected]69023942012-11-30 19:57:1611868}
11869
[email protected]a00c1f742013-03-05 17:02:1611870error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411871 uint32 immediate_data_size,
11872 const void* cmd_data) {
11873 const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c =
11874 *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data);
[email protected]a00c1f742013-03-05 17:02:1611875 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11876 GLenum target = static_cast<GLenum>(c.target);
11877
11878 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5111879 LOCAL_SET_GL_ERROR(
11880 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1611881 return error::kNoError;
11882 }
[email protected]c986af502013-08-14 01:04:4411883 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
11884 &state_, target);
[email protected]370eaf12013-05-18 09:19:4911885 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5111886 LOCAL_SET_GL_ERROR(
11887 GL_INVALID_OPERATION,
11888 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1611889 return error::kNoError;
11890 }
[email protected]896425e2013-06-12 17:27:1811891 AsyncPixelTransferDelegate* delegate =
11892 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
11893 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4911894 LOCAL_SET_GL_ERROR(
11895 GL_INVALID_OPERATION,
11896 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
11897 return error::kNoError;
11898 }
[email protected]896425e2013-06-12 17:27:1811899 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0911900 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1611901 return error::kNoError;
11902}
11903
[email protected]e3c4a9ab2014-03-31 09:07:0211904error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
vmiuracd108592014-09-08 14:36:3411905 uint32 immediate_data_size,
11906 const void* data) {
[email protected]e3c4a9ab2014-03-31 09:07:0211907 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
11908
11909 GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();
11910 ProcessFinishedAsyncTransfers();
11911 return error::kNoError;
11912}
11913
zmo8fab00c2015-02-07 02:45:0511914error::Error GLES2DecoderImpl::HandleUniformBlockBinding(
11915 uint32_t immediate_data_size, const void* cmd_data) {
11916 if (!unsafe_es3_apis_enabled())
11917 return error::kUnknownCommand;
11918 const gles2::cmds::UniformBlockBinding& c =
11919 *static_cast<const gles2::cmds::UniformBlockBinding*>(cmd_data);
11920 GLuint client_id = c.program;
11921 GLuint index = static_cast<GLuint>(c.index);
11922 GLuint binding = static_cast<GLuint>(c.binding);
11923 Program* program = GetProgramInfoNotShader(
11924 client_id, "glUniformBlockBinding");
11925 if (!program) {
11926 return error::kNoError;
11927 }
11928 GLuint service_id = program->service_id();
11929 glUniformBlockBinding(service_id, index, binding);
11930 return error::kNoError;
11931}
11932
[email protected]91c94eb2013-10-22 10:32:5411933void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
11934 TextureRef* texture_ref) {
11935 Texture* texture = texture_ref->texture();
11936 DoDidUseTexImageIfNeeded(texture, texture->target());
11937}
11938
oetuaho37cc50e2014-10-31 11:19:2011939void GLES2DecoderImpl::OnContextLostError() {
11940 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
11941}
11942
[email protected]828a3932014-04-02 14:43:1311943void GLES2DecoderImpl::OnOutOfMemoryError() {
11944 if (lose_context_when_out_of_memory_) {
11945 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]828a3932014-04-02 14:43:1311946 }
11947}
11948
[email protected]96449d2c2009-11-25 00:01:3211949// Include the auto-generated part of this file. We split this because it means
11950// we can easily edit the non-auto generated parts right here in this file
11951// instead of having to edit some template or the code generator.
11952#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
11953
11954} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2511955} // namespace gpu