blob: 55ea6d5ff564d4a661296e7a2fdcacc0a73639d7 [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]d353541f2012-05-03 22:45:4117#include "base/atomicops.h"
[email protected]9d37f062011-11-22 01:24:5218#include "base/bind.h"
[email protected]e844ae22012-01-14 03:36:2619#include "base/command_line.h"
[email protected]1078f912011-12-23 13:12:1420#include "base/debug/trace_event.h"
[email protected]e51bdf32011-11-23 22:21:4621#if defined(OS_MACOSX)
22#include "base/mac/scoped_cftyperef.h"
23#endif
[email protected]3b63f8f42011-03-28 01:54:1524#include "base/memory/scoped_ptr.h"
[email protected]0f8afe82012-05-14 23:43:0125#include "base/string_number_conversions.h"
[email protected]d37231fa2010-04-09 21:16:0226#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3227#define GLES2_GPU_SERVICE 1
28#include "gpu/command_buffer/common/gles2_cmd_format.h"
29#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]d2a0e1a2012-08-12 02:25:0130#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]066849e32010-05-03 19:14:1031#include "gpu/command_buffer/common/id_allocator.h"
[email protected]3916c97e2010-02-25 03:20:5032#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3233#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5034#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2435#include "gpu/command_buffer/service/context_state.h"
[email protected]d3eba342013-04-18 21:11:5036#include "gpu/command_buffer/service/error_state.h"
[email protected]915a59a12010-09-30 21:29:1137#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5838#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3239#include "gpu/command_buffer/service/gl_utils.h"
[email protected]43410e92012-04-20 17:06:2840#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4641#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]e844ae22012-01-14 03:36:2642#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]fb97b662013-02-20 23:02:1443#include "gpu/command_buffer/service/gpu_tracer.h"
[email protected]09d50362012-10-18 20:54:3744#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5945#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2546#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4747#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5348#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5849#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4750#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4551#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0452#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]b0af4f52011-09-28 22:04:4253#include "gpu/command_buffer/service/stream_texture.h"
54#include "gpu/command_buffer/service/stream_texture_manager.h"
[email protected]78b514b2012-05-01 21:50:5955#include "gpu/command_buffer/service/texture_definition.h"
[email protected]a93bb842010-02-16 23:03:4756#include "gpu/command_buffer/service/texture_manager.h"
[email protected]d8ea9772011-07-11 18:11:4357#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]944b62f32012-09-27 02:20:4658#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]32145a92012-12-17 09:01:5959#include "ui/gl/async_pixel_transfer_delegate.h"
[email protected]d8bc3ec2013-03-07 06:28:4060#include "ui/gl/gl_bindings.h"
[email protected]09d50362012-10-18 20:54:3761#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2762#include "ui/gl/gl_implementation.h"
63#include "ui/gl/gl_surface.h"
[email protected]e51bdf32011-11-23 22:21:4664#if defined(OS_MACOSX)
[email protected]d353541f2012-05-03 22:45:4165#include "ui/surface/io_surface_support_mac.h"
[email protected]e51bdf32011-11-23 22:21:4666#endif
[email protected]de17df392010-04-23 21:09:4167
[email protected]693ca512012-11-13 18:09:1368// TODO(zmo): we can't include "City.h" due to type def conflicts.
69extern uint64 CityHash64(const char*, size_t);
70
[email protected]a7a27ace2009-12-12 00:11:2571namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3272namespace gles2 {
73
[email protected]f0d74742011-10-03 16:31:0474namespace {
[email protected]693ca512012-11-13 18:09:1375
[email protected]f0d74742011-10-03 16:31:0476static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]693ca512012-11-13 18:09:1377
[email protected]3d944a82013-02-12 19:09:0278#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]693ca512012-11-13 18:09:1379khronos_uint64_t CityHashForAngle(const char* name, unsigned int len) {
80 return static_cast<khronos_uint64_t>(
81 CityHash64(name, static_cast<size_t>(len)));
82}
[email protected]3d944a82013-02-12 19:09:0283#endif
[email protected]693ca512012-11-13 18:09:1384
[email protected]8dc1bf92013-03-12 03:58:2185static void GetShaderPrecisionFormatImpl(GLenum shader_type,
86 GLenum precision_type,
87 GLint *range, GLint *precision) {
88 switch (precision_type) {
89 case GL_LOW_INT:
90 case GL_MEDIUM_INT:
91 case GL_HIGH_INT:
92 // These values are for a 32-bit twos-complement integer format.
93 range[0] = 31;
94 range[1] = 30;
95 *precision = 0;
96 break;
97 case GL_LOW_FLOAT:
98 case GL_MEDIUM_FLOAT:
99 case GL_HIGH_FLOAT:
100 // These values are for an IEEE single-precision floating-point format.
101 range[0] = 127;
102 range[1] = 127;
103 *precision = 23;
104 break;
105 default:
106 NOTREACHED();
107 break;
108 }
109
[email protected]8af4d5e2013-03-15 23:55:33110 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
111 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21112 // This function is sometimes defined even though it's really just
113 // a stub, so we need to set range and precision as if it weren't
114 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44115 // On Mac OS with some GPUs, calling this generates a
116 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
117 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21118 glGetShaderPrecisionFormat(shader_type, precision_type,
119 range, precision);
120 }
121}
122
[email protected]b04e24c2013-01-08 18:35:25123} // namespace
[email protected]f0d74742011-10-03 16:31:04124
[email protected]6217d392010-03-25 22:08:35125class GLES2DecoderImpl;
126
[email protected]ab09b612013-03-11 22:11:51127// Local versions of the SET_GL_ERROR macros
128#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50129 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51130#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50131 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
132 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51133#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50134 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
135 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51136#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50137 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
138 function_name)
[email protected]ab09b612013-03-11 22:11:51139#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50140 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51141#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50142 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51143#define LOCAL_PERFORMANCE_WARNING(msg) \
144 PerformanceWarning(__FILE__, __LINE__, msg)
145#define LOCAL_RENDER_WARNING(msg) \
146 RenderWarning(__FILE__, __LINE__, msg)
147
[email protected]07f54fcc2009-12-22 02:46:30148// Check that certain assumptions the code makes are true. There are places in
149// the code where shared memory is passed direclty to GL. Example, glUniformiv,
150// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
151// a few others) are 32bits. If they are not 32bits the code will have to change
152// to call those GL functions with service side memory and then copy the results
153// to shared memory, converting the sizes.
154COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
155 GLint_not_same_size_as_uint32);
156COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
157 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37158COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
159 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30160
[email protected]43f28f832010-02-03 02:28:48161// TODO(kbr): the use of this anonymous namespace core dumps the
162// linker on Mac OS X 10.6 when the symbol ordering file is used
163// namespace {
[email protected]96449d2c2009-11-25 00:01:32164
165// Returns the address of the first byte after a struct.
166template <typename T>
167const void* AddressAfterStruct(const T& pod) {
168 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
169}
170
[email protected]07f54fcc2009-12-22 02:46:30171// Returns the address of the frst byte after the struct or NULL if size >
172// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32173template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30174RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
175 uint32 size,
176 uint32 immediate_data_size) {
177 return (size <= immediate_data_size) ?
178 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
179 NULL;
[email protected]96449d2c2009-11-25 00:01:32180}
181
[email protected]07f54fcc2009-12-22 02:46:30182// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18183bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32184 GLuint count,
185 size_t size,
[email protected]a76b0052010-03-05 00:33:18186 unsigned int elements_per_unit,
187 uint32* dst) {
188 uint32 value;
189 if (!SafeMultiplyUint32(count, size, &value)) {
190 return false;
191 }
192 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
193 return false;
194 }
195 *dst = value;
196 return true;
[email protected]96449d2c2009-11-25 00:01:32197}
198
199// A struct to hold info about each command.
200struct CommandInfo {
201 int arg_flags; // How to handle the arguments for this command
202 int arg_count; // How many arguments are expected for this command.
203};
204
205// A table of CommandInfo for all the commands.
206const CommandInfo g_command_info[] = {
[email protected]ed9f9cd2013-02-27 21:12:35207 #define GLES2_CMD_OP(name) { \
208 cmds::name::kArgFlags, \
209 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \
[email protected]96449d2c2009-11-25 00:01:32210
211 GLES2_COMMAND_LIST(GLES2_CMD_OP)
212
213 #undef GLES2_CMD_OP
214};
215
[email protected]258a3313f2011-10-18 20:13:57216// Return true if a character belongs to the ASCII subset as defined in
217// GLSL ES 1.0 spec section 3.1.
218static bool CharacterIsValidForGLES(unsigned char c) {
219 // Printing characters are valid except " $ ` @ \ ' DEL.
220 if (c >= 32 && c <= 126 &&
221 c != '"' &&
222 c != '$' &&
223 c != '`' &&
224 c != '@' &&
225 c != '\\' &&
226 c != '\'') {
227 return true;
228 }
229 // Horizontal tab, line feed, vertical tab, form feed, carriage return
230 // are also valid.
231 if (c >= 9 && c <= 13) {
232 return true;
233 }
234
235 return false;
236}
237
238static bool StringIsValidForGLES(const char* str) {
239 for (; *str; ++str) {
240 if (!CharacterIsValidForGLES(*str)) {
241 return false;
242 }
243 }
244 return true;
245}
246
[email protected]f0e6a34f2012-01-04 20:53:40247static inline GLenum GetTexInternalFormat(GLenum internal_format) {
248 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
249 if (internal_format == GL_BGRA_EXT || internal_format == GL_BGRA8_EXT)
250 return GL_RGBA8;
251 }
252 return internal_format;
253}
254
[email protected]32145a92012-12-17 09:01:59255// TODO(epenner): Could the above function be merged into this and removed?
256static inline GLenum GetTexInternalFormat(GLenum internal_format,
257 GLenum format,
258 GLenum type) {
259 GLenum gl_internal_format = GetTexInternalFormat(internal_format);
260
261 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
262 return gl_internal_format;
263
264 if (type == GL_FLOAT) {
265 switch (format) {
266 case GL_RGBA:
267 gl_internal_format = GL_RGBA32F_ARB;
268 break;
269 case GL_RGB:
270 gl_internal_format = GL_RGB32F_ARB;
271 break;
272 case GL_LUMINANCE_ALPHA:
273 gl_internal_format = GL_LUMINANCE_ALPHA32F_ARB;
274 break;
275 case GL_LUMINANCE:
276 gl_internal_format = GL_LUMINANCE32F_ARB;
277 break;
278 case GL_ALPHA:
279 gl_internal_format = GL_ALPHA32F_ARB;
280 break;
281 default:
282 NOTREACHED();
283 break;
284 }
285 } else if (type == GL_HALF_FLOAT_OES) {
286 switch (format) {
287 case GL_RGBA:
288 gl_internal_format = GL_RGBA16F_ARB;
289 break;
290 case GL_RGB:
291 gl_internal_format = GL_RGB16F_ARB;
292 break;
293 case GL_LUMINANCE_ALPHA:
294 gl_internal_format = GL_LUMINANCE_ALPHA16F_ARB;
295 break;
296 case GL_LUMINANCE:
297 gl_internal_format = GL_LUMINANCE16F_ARB;
298 break;
299 case GL_ALPHA:
300 gl_internal_format = GL_ALPHA16F_ARB;
301 break;
302 default:
303 NOTREACHED();
304 break;
305 }
306 }
307 return gl_internal_format;
308}
309
[email protected]297ca1c2011-06-20 23:08:46310static void WrappedTexImage2D(
[email protected]473c01ccb2011-06-07 01:33:30311 GLenum target,
312 GLint level,
313 GLenum internal_format,
314 GLsizei width,
315 GLsizei height,
316 GLint border,
317 GLenum format,
318 GLenum type,
319 const void* pixels) {
[email protected]473c01ccb2011-06-07 01:33:30320 glTexImage2D(
[email protected]32145a92012-12-17 09:01:59321 target, level, GetTexInternalFormat(internal_format, format, type),
322 width, height, border, format, type, pixels);
[email protected]473c01ccb2011-06-07 01:33:30323}
324
[email protected]297ca1c2011-06-20 23:08:46325// Wrapper for glEnable/glDisable that doesn't suck.
326static void EnableDisable(GLenum pname, bool enable) {
327 if (enable) {
328 glEnable(pname);
329 } else {
330 glDisable(pname);
331 }
332}
333
[email protected]6217d392010-03-25 22:08:35334// This class prevents any GL errors that occur when it is in scope from
335// being reported to the client.
336class ScopedGLErrorSuppressor {
337 public:
[email protected]ab09b612013-03-11 22:11:51338 explicit ScopedGLErrorSuppressor(
339 const char* function_name, GLES2DecoderImpl* decoder);
[email protected]6217d392010-03-25 22:08:35340 ~ScopedGLErrorSuppressor();
341 private:
[email protected]ab09b612013-03-11 22:11:51342 const char* function_name_;
[email protected]6217d392010-03-25 22:08:35343 GLES2DecoderImpl* decoder_;
344 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
345};
346
347// Temporarily changes a decoder's bound 2D texture and restore it when this
348// object goes out of scope. Also temporarily switches to using active texture
349// unit zero in case the client has changed that to something invalid.
350class ScopedTexture2DBinder {
351 public:
352 ScopedTexture2DBinder(GLES2DecoderImpl* decoder, GLuint id);
353 ~ScopedTexture2DBinder();
354
355 private:
356 GLES2DecoderImpl* decoder_;
357 DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder);
358};
359
360// Temporarily changes a decoder's bound render buffer and restore it when this
361// object goes out of scope.
362class ScopedRenderBufferBinder {
363 public:
364 ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
365 ~ScopedRenderBufferBinder();
366
367 private:
368 GLES2DecoderImpl* decoder_;
369 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
370};
371
372// Temporarily changes a decoder's bound frame buffer and restore it when this
373// object goes out of scope.
374class ScopedFrameBufferBinder {
375 public:
376 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
377 ~ScopedFrameBufferBinder();
378
379 private:
380 GLES2DecoderImpl* decoder_;
381 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
382};
383
[email protected]34ff8b0c2010-10-01 20:06:02384// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52385// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27386// if it is bound or enforce_internal_framebuffer is true. If internal is
387// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02388class ScopedResolvedFrameBufferBinder {
389 public:
[email protected]e7e38032011-07-26 17:25:25390 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
[email protected]de26b3c2011-08-03 21:54:27391 bool enforce_internal_framebuffer,
392 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02393 ~ScopedResolvedFrameBufferBinder();
394
395 private:
396 GLES2DecoderImpl* decoder_;
397 bool resolve_and_bind_;
398 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
399};
400
[email protected]63b465922012-09-06 02:04:52401// This class records texture upload time when in scope.
402class ScopedTextureUploadTimer {
403 public:
404 explicit ScopedTextureUploadTimer(GLES2DecoderImpl* decoder);
405 ~ScopedTextureUploadTimer();
406
407 private:
408 GLES2DecoderImpl* decoder_;
409 base::TimeTicks begin_time_;
410 DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer);
411};
412
[email protected]6217d392010-03-25 22:08:35413// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35414class BackTexture {
[email protected]6217d392010-03-25 22:08:35415 public:
[email protected]ed9f9cd2013-02-27 21:12:35416 explicit BackTexture(GLES2DecoderImpl* decoder);
417 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35418
419 // Create a new render texture.
420 void Create();
421
422 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09423 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35424
425 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58426 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35427
428 // Destroy the render texture. This must be explicitly called before
429 // destroying this object.
430 void Destroy();
431
[email protected]97872062010-11-03 19:07:05432 // Invalidate the texture. This can be used when a context is lost and it is
433 // not possible to make it current in order to free the resource.
434 void Invalidate();
435
[email protected]6217d392010-03-25 22:08:35436 GLuint id() const {
437 return id_;
438 }
439
[email protected]d37231fa2010-04-09 21:16:02440 gfx::Size size() const {
441 return size_;
442 }
443
[email protected]1078f912011-12-23 13:12:14444 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25445 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14446 }
447
[email protected]6217d392010-03-25 22:08:35448 private:
449 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25450 MemoryTypeTracker memory_tracker_;
[email protected]68e81a4a62012-12-13 01:16:48451 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35452 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02453 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35454 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35455};
456
457// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35458class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35459 public:
[email protected]ed9f9cd2013-02-27 21:12:35460 explicit BackRenderbuffer(GLES2DecoderImpl* decoder);
461 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35462
463 // Create a new render buffer.
464 void Create();
465
466 // Set the initial size and format of a render buffer or resize it.
[email protected]34ff8b0c2010-10-01 20:06:02467 bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples);
[email protected]6217d392010-03-25 22:08:35468
469 // Destroy the render buffer. This must be explicitly called before destroying
470 // this object.
471 void Destroy();
472
[email protected]97872062010-11-03 19:07:05473 // Invalidate the render buffer. This can be used when a context is lost and
474 // it is not possible to make it current in order to free the resource.
475 void Invalidate();
476
[email protected]6217d392010-03-25 22:08:35477 GLuint id() const {
478 return id_;
479 }
480
[email protected]1078f912011-12-23 13:12:14481 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25482 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14483 }
484
[email protected]6217d392010-03-25 22:08:35485 private:
486 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25487 MemoryTypeTracker memory_tracker_;
[email protected]68e81a4a62012-12-13 01:16:48488 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35489 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35490 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35491};
492
493// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35494class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35495 public:
[email protected]ed9f9cd2013-02-27 21:12:35496 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
497 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35498
499 // Create a new frame buffer.
500 void Create();
501
502 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35503 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35504
[email protected]b9363b22010-06-09 22:06:15505 // Attach a render buffer to a frame buffer. Note that this unbinds any
506 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35507 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35508
[email protected]6217d392010-03-25 22:08:35509 // Destroy the frame buffer. This must be explicitly called before destroying
510 // this object.
511 void Destroy();
512
[email protected]97872062010-11-03 19:07:05513 // Invalidate the frame buffer. This can be used when a context is lost and it
514 // is not possible to make it current in order to free the resource.
515 void Invalidate();
516
[email protected]6217d392010-03-25 22:08:35517 // See glCheckFramebufferStatusEXT.
518 GLenum CheckStatus();
519
520 GLuint id() const {
521 return id_;
522 }
523
524 private:
525 GLES2DecoderImpl* decoder_;
526 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35527 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35528};
[email protected]34ff8b0c2010-10-01 20:06:02529
[email protected]43f28f832010-02-03 02:28:48530// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32531
[email protected]ddb1e5a2010-12-13 20:10:45532bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
533 uint32* service_texture_id) {
534 return false;
535}
536
[email protected]a3ded6d2010-10-19 06:44:39537GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06538 : initialized_(false),
539 debug_(false),
[email protected]1d82e822013-04-10 21:32:32540 log_commands_(false) {
[email protected]96449d2c2009-11-25 00:01:32541}
542
[email protected]3916c97e2010-02-25 03:20:50543GLES2Decoder::~GLES2Decoder() {
544}
545
[email protected]57edfdad2012-02-07 04:57:15546bool GLES2Decoder::testing_force_is_angle_;
547
548void GLES2Decoder::set_testing_force_is_angle(bool force) {
549 testing_force_is_angle_ = force;
550}
551
552bool GLES2Decoder::IsAngle() {
553#if defined(OS_WIN)
554 return testing_force_is_angle_ ||
555 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2;
556#else
557 return testing_force_is_angle_;
558#endif
559}
560
[email protected]f39f4b3f2010-05-12 17:04:08561// This class implements GLES2Decoder so we don't have to expose all the GLES2
562// cmd stuff to outside this class.
[email protected]ee1e6aa2012-11-29 09:24:10563class GLES2DecoderImpl : public GLES2Decoder {
[email protected]f39f4b3f2010-05-12 17:04:08564 public:
[email protected]476ccb72012-12-06 15:52:52565 // Used by PrepForSetUniformByLocation to validate types.
566 struct BaseUniformInfo {
567 const GLenum* const valid_types;
568 size_t num_valid_types;
569 };
570
[email protected]aa7666122011-09-02 19:45:52571 explicit GLES2DecoderImpl(ContextGroup* group);
[email protected]b8e97b62012-09-30 15:09:00572 virtual ~GLES2DecoderImpl();
[email protected]f39f4b3f2010-05-12 17:04:08573
[email protected]96449d2c2009-11-25 00:01:32574 // Overridden from AsyncAPIInterface.
[email protected]f7a64ee2010-02-01 22:24:14575 virtual Error DoCommand(unsigned int command,
[email protected]3916c97e2010-02-25 03:20:50576 unsigned int arg_count,
[email protected]b8e97b62012-09-30 15:09:00577 const void* args) OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32578
579 // Overridden from AsyncAPIInterface.
[email protected]b8e97b62012-09-30 15:09:00580 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32581
582 // Overridden from GLES2Decoder.
[email protected]fbe20372011-06-01 01:46:38583 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
584 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:23585 bool offscreen,
[email protected]6217d392010-03-25 22:08:35586 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29587 const DisallowedFeatures& disallowed_features,
[email protected]a3ded6d2010-10-19 06:44:39588 const char* allowed_extensions,
[email protected]b8e97b62012-09-30 15:09:00589 const std::vector<int32>& attribs) OVERRIDE;
590 virtual void Destroy(bool have_context) OVERRIDE;
[email protected]63c9b052012-05-17 18:27:38591 virtual void SetSurface(
592 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
[email protected]3c644d82011-06-20 19:58:24593 virtual bool SetParent(GLES2Decoder* parent_decoder,
[email protected]b8e97b62012-09-30 15:09:00594 uint32 parent_texture_id) OVERRIDE;
595 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
[email protected]9a5afa432011-07-22 18:16:39596 void UpdateParentTextureInfo();
[email protected]b8e97b62012-09-30 15:09:00597 virtual bool MakeCurrent() OVERRIDE;
598 virtual void ReleaseCurrent() OVERRIDE;
599 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
600 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
601 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
[email protected]1868a342012-11-07 15:56:02602 virtual void RestoreState() const OVERRIDE;
[email protected]29a4d902013-02-26 20:18:06603
604 virtual void RestoreActiveTexture() const OVERRIDE {
605 state_.RestoreActiveTexture();
606 }
607 virtual void RestoreAttribute(unsigned index) const OVERRIDE {
608 state_.RestoreAttribute(index);
609 }
610 virtual void RestoreBufferBindings() const OVERRIDE {
611 state_.RestoreBufferBindings();
612 }
613 virtual void RestoreGlobalState() const OVERRIDE {
614 state_.RestoreGlobalState();
615 }
616 virtual void RestoreProgramBindings() const OVERRIDE {
617 state_.RestoreProgramBindings();
618 }
619 virtual void RestoreRenderbufferBindings() const OVERRIDE {
620 state_.RestoreRenderbufferBindings();
621 }
622 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE {
623 state_.RestoreTextureUnitBindings(unit);
624 }
625 virtual void RestoreFramebufferBindings() const OVERRIDE;
626 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE;
627
[email protected]b8e97b62012-09-30 15:09:00628 virtual QueryManager* GetQueryManager() OVERRIDE {
629 return query_manager_.get();
630 }
631 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
[email protected]944b62f32012-09-27 02:20:46632 return vertex_array_manager_.get();
633 }
[email protected]b8e97b62012-09-30 15:09:00634 virtual bool ProcessPendingQueries() OVERRIDE;
[email protected]2b1767cf2013-03-16 09:25:05635 virtual bool HasMoreIdleWork() OVERRIDE;
636 virtual void PerformIdleWork() OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48637
[email protected]9d37f062011-11-22 01:24:52638 virtual void SetResizeCallback(
[email protected]b8e97b62012-09-30 15:09:00639 const base::Callback<void(gfx::Size)>& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00640
[email protected]1d82e822013-04-10 21:32:32641 virtual Logger* GetLogger() OVERRIDE;
[email protected]d3eba342013-04-18 21:11:50642 virtual ErrorState* GetErrorState() OVERRIDE;
[email protected]1d82e822013-04-10 21:32:32643
[email protected]e3932abb2013-03-13 00:01:37644 virtual void SetShaderCacheCallback(
645 const ShaderCacheCallback& callback) OVERRIDE;
[email protected]840a7e462013-02-27 01:29:51646 virtual void SetWaitSyncPointCallback(
647 const WaitSyncPointCallback& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00648
[email protected]b8e97b62012-09-30 15:09:00649 virtual void SetStreamTextureManager(StreamTextureManager* manager) OVERRIDE;
[email protected]32145a92012-12-17 09:01:59650
651 virtual gfx::AsyncPixelTransferDelegate*
652 GetAsyncPixelTransferDelegate() OVERRIDE;
653 virtual void SetAsyncPixelTransferDelegate(
654 gfx::AsyncPixelTransferDelegate* delegate) OVERRIDE;
[email protected]69a8701e2013-03-07 21:31:09655 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59656
[email protected]1318e922010-09-17 22:03:16657 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00658 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48659
[email protected]63b465922012-09-06 02:04:52660 virtual uint32 GetTextureUploadCount() OVERRIDE;
661 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
662 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30663 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52664
[email protected]8e3e0662010-08-23 18:46:30665 // Restores the current state to the user's settings.
666 void RestoreCurrentFramebufferBindings();
667 void RestoreCurrentRenderbufferBindings();
668 void RestoreCurrentTexture2DBindings();
669
[email protected]297ca1c2011-06-20 23:08:46670 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
671 void ApplyDirtyState();
672
673 // These check the state of the currently bound framebuffer or the
674 // backbuffer if no framebuffer is bound.
675 bool BoundFramebufferHasColorAttachmentWithAlpha();
676 bool BoundFramebufferHasDepthAttachment();
677 bool BoundFramebufferHasStencilAttachment();
678
[email protected]b8e97b62012-09-30 15:09:00679 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43680
[email protected]96449d2c2009-11-25 00:01:32681 private:
[email protected]70d34263c2013-01-09 00:27:45682 friend class ScopedFrameBufferBinder;
[email protected]6217d392010-03-25 22:08:35683 friend class ScopedGLErrorSuppressor;
[email protected]34ff8b0c2010-10-01 20:06:02684 friend class ScopedResolvedFrameBufferBinder;
[email protected]63b465922012-09-06 02:04:52685 friend class ScopedTextureUploadTimer;
[email protected]ed9f9cd2013-02-27 21:12:35686 friend class BackTexture;
687 friend class BackRenderbuffer;
688 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35689
[email protected]c2f8c8402010-12-06 18:07:24690 // Initialize or re-initialize the shader translator.
691 bool InitializeShaderTranslator();
692
[email protected]302ce6d2011-07-07 23:28:11693 void UpdateCapabilities();
694
[email protected]ae51d192010-04-27 00:48:03695 // Helpers for the glGen and glDelete functions.
696 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
697 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
698 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
699 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
700 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
701 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
702 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
703 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53704 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
705 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46706 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
707 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47708
[email protected]70d34263c2013-01-09 00:27:45709 // Workarounds
710 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51711 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45712
[email protected]3916c97e2010-02-25 03:20:50713 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50714 BufferManager* buffer_manager() {
715 return group_->buffer_manager();
716 }
717
[email protected]a25fa872010-03-25 02:57:58718 RenderbufferManager* renderbuffer_manager() {
719 return group_->renderbuffer_manager();
720 }
721
722 FramebufferManager* framebuffer_manager() {
723 return group_->framebuffer_manager();
724 }
725
[email protected]3916c97e2010-02-25 03:20:50726 ProgramManager* program_manager() {
727 return group_->program_manager();
728 }
729
730 ShaderManager* shader_manager() {
731 return group_->shader_manager();
732 }
733
[email protected]29a4d902013-02-26 20:18:06734 const TextureManager* texture_manager() const {
735 return group_->texture_manager();
736 }
737
[email protected]3916c97e2010-02-25 03:20:50738 TextureManager* texture_manager() {
739 return group_->texture_manager();
740 }
741
[email protected]78b514b2012-05-01 21:50:59742 MailboxManager* mailbox_manager() {
743 return group_->mailbox_manager();
744 }
745
[email protected]09d50362012-10-18 20:54:37746 ImageManager* image_manager() {
747 return group_->image_manager();
748 }
749
[email protected]944b62f32012-09-27 02:20:46750 VertexArrayManager* vertex_array_manager() {
751 return vertex_array_manager_.get();
752 }
753
[email protected]7989c9e2013-01-23 06:39:26754 MemoryTracker* memory_tracker() {
755 return group_->memory_tracker();
756 }
757
758 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
759 MemoryTracker* tracker = memory_tracker();
760 if (tracker) {
761 return tracker->EnsureGPUMemoryAvailable(estimated_size);
762 }
763 return true;
764 }
765
[email protected]34ff8b0c2010-10-01 20:06:02766 bool IsOffscreenBufferMultisampled() const {
767 return offscreen_target_samples_ > 1;
768 }
769
[email protected]ed9f9cd2013-02-27 21:12:35770 // Creates a Texture for the given texture.
771 Texture* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03772 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35773 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47774 }
775
776 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35777 Texture* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07778 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47779 }
780
781 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35782 void RemoveTexture(GLuint client_id) {
783 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50784 }
[email protected]a93bb842010-02-16 23:03:47785
[email protected]d37231fa2010-04-09 21:16:02786 // Get the size (in pixels) of the currently bound frame buffer (either FBO
787 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30788 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02789
[email protected]9edc6b22010-12-23 02:00:26790 // Get the format of the currently bound frame buffer (either FBO or regular
791 // back buffer)
792 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46793 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26794
[email protected]a93bb842010-02-16 23:03:47795 // Wrapper for CompressedTexImage2D commands.
796 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37797 GLenum target,
798 GLint level,
799 GLenum internal_format,
800 GLsizei width,
801 GLsizei height,
802 GLint border,
803 GLsizei image_size,
804 const void* data);
[email protected]a93bb842010-02-16 23:03:47805
[email protected]cadde4a2010-07-31 17:10:43806 // Wrapper for CompressedTexSubImage2D.
807 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37808 GLenum target,
809 GLint level,
810 GLint xoffset,
811 GLint yoffset,
812 GLsizei width,
813 GLsizei height,
814 GLenum format,
815 GLsizei imageSize,
816 const void * data);
[email protected]cadde4a2010-07-31 17:10:43817
818 // Wrapper for CopyTexImage2D.
819 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37820 GLenum target,
821 GLint level,
822 GLenum internal_format,
823 GLint x,
824 GLint y,
825 GLsizei width,
826 GLsizei height,
827 GLint border);
[email protected]cadde4a2010-07-31 17:10:43828
829 // Wrapper for CopyTexSubImage2D.
830 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37831 GLenum target,
832 GLint level,
833 GLint xoffset,
834 GLint yoffset,
835 GLint x,
836 GLint y,
837 GLsizei width,
838 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43839
[email protected]f598f422012-12-07 08:30:03840 // Validation for TexImage2D commands.
841 bool ValidateTexImage2D(
842 const char* function_name,
[email protected]09d50362012-10-18 20:54:37843 GLenum target,
844 GLint level,
845 GLenum internal_format,
846 GLsizei width,
847 GLsizei height,
848 GLint border,
849 GLenum format,
850 GLenum type,
851 const void* pixels,
852 uint32 pixels_size);
[email protected]a93bb842010-02-16 23:03:47853
[email protected]f598f422012-12-07 08:30:03854 // Wrapper for TexImage2D commands.
855 void DoTexImage2D(
856 GLenum target,
857 GLint level,
858 GLenum internal_format,
859 GLsizei width,
860 GLsizei height,
861 GLint border,
862 GLenum format,
863 GLenum type,
864 const void* pixels,
865 uint32 pixels_size);
866
867 // Validation for TexSubImage2D.
868 bool ValidateTexSubImage2D(
869 error::Error* error,
870 const char* function_name,
871 GLenum target,
872 GLint level,
873 GLint xoffset,
874 GLint yoffset,
875 GLsizei width,
876 GLsizei height,
877 GLenum format,
878 GLenum type,
879 const void * data);
880
[email protected]cadde4a2010-07-31 17:10:43881 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03882 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37883 GLenum target,
884 GLint level,
885 GLint xoffset,
886 GLint yoffset,
887 GLsizei width,
888 GLsizei height,
889 GLenum format,
890 GLenum type,
891 const void * data);
[email protected]cadde4a2010-07-31 17:10:43892
[email protected]32145a92012-12-17 09:01:59893 // Extra validation for async tex(Sub)Image2D.
894 bool ValidateAsyncTransfer(
895 const char* function_name,
[email protected]02965c22013-03-09 02:40:07896 Texture* texture,
[email protected]32145a92012-12-17 09:01:59897 GLenum target,
898 GLint level,
899 const void * data);
900
[email protected]e51bdf32011-11-23 22:21:46901 // Wrapper for TexImageIOSurface2DCHROMIUM.
902 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37903 GLenum target,
904 GLsizei width,
905 GLsizei height,
906 GLuint io_surface_id,
907 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46908
[email protected]43410e92012-04-20 17:06:28909 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37910 GLenum target,
911 GLuint source_id,
912 GLuint target_id,
913 GLint level,
914 GLenum internal_format);
[email protected]43410e92012-04-20 17:06:28915
[email protected]97dc7cbe2011-12-06 17:26:17916 // Wrapper for TexStorage2DEXT.
917 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37918 GLenum target,
919 GLint levels,
920 GLenum internal_format,
921 GLsizei width,
922 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17923
[email protected]78b514b2012-05-01 21:50:59924 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
925 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
926
[email protected]09d50362012-10-18 20:54:37927 void DoBindTexImage2DCHROMIUM(
928 GLenum target,
929 GLint image_id);
930 void DoReleaseTexImage2DCHROMIUM(
931 GLenum target,
932 GLint image_id);
933
[email protected]94307712012-11-16 23:26:11934 void DoTraceEndCHROMIUM(void);
935
[email protected]2f143d482013-03-14 18:04:49936 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
937
[email protected]ed9f9cd2013-02-27 21:12:35938 // Creates a Program for the given program.
939 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57940 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35941 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47942 }
943
[email protected]07f54fcc2009-12-22 02:46:30944 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35945 Program* GetProgram(GLuint client_id) {
946 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46947 }
[email protected]07f54fcc2009-12-22 02:46:30948
[email protected]cae20172012-12-07 00:06:19949#if defined(NDEBUG)
950 void LogClientServiceMapping(
951 const char* /* function_name */,
952 GLuint /* client_id */,
953 GLuint /* service_id */) {
954 }
955 template<typename T>
956 void LogClientServiceForInfo(
957 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
958 }
959#else
960 void LogClientServiceMapping(
961 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:26962 if (service_logging_) {
[email protected]1d82e822013-04-10 21:32:32963 DLOG(INFO) << "[" << logger_.GetLogPrefix() << "] " << function_name
[email protected]2a22fe72012-12-07 04:21:26964 << ": client_id = " << client_id
965 << ", service_id = " << service_id;
966 }
[email protected]cae20172012-12-07 00:06:19967 }
968 template<typename T>
969 void LogClientServiceForInfo(
970 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:26971 if (info) {
[email protected]cae20172012-12-07 00:06:19972 LogClientServiceMapping(function_name, client_id, info->service_id());
973 }
974 }
975#endif
976
[email protected]6b8cf1a2010-05-06 16:13:58977 // Gets the program info for the given program. If it's not a program
978 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:35979 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:58980 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42981 Program* program = GetProgram(client_id);
982 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:35983 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:51984 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43985 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:58986 } else {
[email protected]ab09b612013-03-11 22:11:51987 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:58988 }
989 }
[email protected]df37b9932013-03-08 05:21:42990 LogClientServiceForInfo(program, client_id, function_name);
991 return program;
[email protected]6b8cf1a2010-05-06 16:13:58992 }
993
994
[email protected]ed9f9cd2013-02-27 21:12:35995 // Creates a Shader for the given shader.
996 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:57997 GLuint client_id,
998 GLuint service_id,
999 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:351000 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:571001 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:311002 }
1003
1004 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:351005 Shader* GetShader(GLuint client_id) {
1006 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:311007 }
1008
[email protected]6b8cf1a2010-05-06 16:13:581009 // Gets the shader info for the given shader. If it's not a shader generates a
1010 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:351011 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:581012 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:421013 Shader* shader = GetShader(client_id);
1014 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:351015 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:511016 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431017 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:581018 } else {
[email protected]ab09b612013-03-11 22:11:511019 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:431020 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:581021 }
1022 }
[email protected]df37b9932013-03-08 05:21:421023 LogClientServiceForInfo(shader, client_id, function_name);
1024 return shader;
[email protected]6b8cf1a2010-05-06 16:13:581025 }
1026
[email protected]a93bb842010-02-16 23:03:471027 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:351028 void CreateBuffer(GLuint client_id, GLuint service_id) {
1029 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:471030 }
1031
[email protected]07f54fcc2009-12-22 02:46:301032 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:211033 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:071034 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
1035 return buffer;
[email protected]1d32bc82010-01-13 22:06:461036 }
[email protected]07f54fcc2009-12-22 02:46:301037
[email protected]a93bb842010-02-16 23:03:471038 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1039 // on glDeleteBuffers so we can make sure the user does not try to render
1040 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351041 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471042
[email protected]a25fa872010-03-25 02:57:581043 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351044 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1045 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581046 }
1047
1048 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061049 Framebuffer* GetFramebuffer(GLuint client_id) {
1050 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581051 }
1052
1053 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351054 void RemoveFramebuffer(GLuint client_id) {
1055 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581056 }
1057
1058 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351059 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1060 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031061 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581062 }
1063
1064 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271065 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1066 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581067 }
1068
1069 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351070 void RemoveRenderbuffer(GLuint client_id) {
1071 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581072 }
1073
[email protected]944b62f32012-09-27 02:20:461074 // Gets the vertex attrib manager for the given vertex array.
1075 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1076 VertexAttribManager* info =
1077 vertex_array_manager()->GetVertexAttribManager(client_id);
1078 return info;
1079 }
1080
1081 // Removes the vertex attrib manager for the given vertex array.
1082 void RemoveVertexAttribManager(GLuint client_id) {
1083 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1084 }
1085
1086 // Creates a vertex attrib manager for the given vertex array.
1087 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) {
1088 return vertex_array_manager()->CreateVertexAttribManager(
1089 client_id, service_id, group_->max_vertex_attribs());
1090 }
1091
[email protected]258a3313f2011-10-18 20:13:571092 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331093 void DoBindUniformLocationCHROMIUM(
1094 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571095
[email protected]558847a2010-03-24 07:02:541096 error::Error GetAttribLocationHelper(
1097 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1098 const std::string& name_str);
1099
1100 error::Error GetUniformLocationHelper(
1101 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1102 const std::string& name_str);
1103
[email protected]3916c97e2010-02-25 03:20:501104 // Helper for glShaderSource.
1105 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031106 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301107
[email protected]0d6bfdc2011-11-02 01:32:201108 // Clear any textures used by the current program.
1109 bool ClearUnclearedTextures();
1110
1111 // Clear any uncleared level in texture.
1112 // Returns false if there was a generated GL error.
[email protected]02965c22013-03-09 02:40:071113 bool ClearTexture(Texture* texture);
[email protected]0d6bfdc2011-11-02 01:32:201114
1115 // Clears any uncleared attachments attached to the given frame buffer.
1116 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061117 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281118
[email protected]0d6bfdc2011-11-02 01:32:201119 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:001120 virtual bool ClearLevel(unsigned service_id,
1121 unsigned bind_target,
1122 unsigned target,
1123 int level,
1124 unsigned format,
1125 unsigned type,
1126 int width,
1127 int height,
1128 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:201129
[email protected]c007aa02010-09-02 22:22:401130 // Restore all GL state that affects clearing.
1131 void RestoreClearState();
1132
[email protected]3a2e7c7b2010-08-06 01:12:281133 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461134 // Returns: true if glEnable/glDisable should actually be called.
1135 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281136
[email protected]0d6bfdc2011-11-02 01:32:201137 // Check that the currently bound framebuffers are valid.
1138 // Generates GL error if not.
1139 bool CheckBoundFramebuffersValid(const char* func_name);
1140
1141 // Check if a framebuffer meets our requirements.
1142 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351143 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201144 GLenum target,
1145 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271146
[email protected]939e7362010-05-13 20:49:101147 // Checks if the current program exists and is valid. If not generates the
1148 // appropriate GL error. Returns true if the current program is in a usable
1149 // state.
1150 bool CheckCurrentProgram(const char* function_name);
1151
1152 // Checks if the current program exists and is valid and that location is not
1153 // -1. If the current program is not valid generates the appropriate GL
1154 // error. Returns true if the current program is in a usable state and
1155 // location is not -1.
1156 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1157
1158 // Gets the type of a uniform for a location in the current program. Sets GL
1159 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361160 // program is valid and the location exists. Adjusts count so it
1161 // does not overflow the uniform.
1162 bool PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:121163 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:521164 const BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:121165 GLint* real_location, GLenum* type, GLsizei* count);
[email protected]939e7362010-05-13 20:49:101166
[email protected]b177ae22011-11-01 03:29:111167 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021168 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111169
[email protected]b273e432010-04-12 17:23:581170 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1171 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1172
[email protected]ac77603c72013-03-08 13:52:061173 // Helper for glGetVertexAttrib
1174 void GetVertexAttribHelper(
1175 const VertexAttrib* attrib, GLenum pname, GLint* param);
1176
[email protected]96449d2c2009-11-25 00:01:321177 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031178 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321179
1180 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031181 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321182
[email protected]3916c97e2010-02-25 03:20:501183 // Wrapper for glActiveTexture
1184 void DoActiveTexture(GLenum texture_unit);
1185
[email protected]ae51d192010-04-27 00:48:031186 // Wrapper for glAttachShader
1187 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1188
[email protected]96449d2c2009-11-25 00:01:321189 // Wrapper for glBindBuffer since we need to track the current targets.
1190 void DoBindBuffer(GLenum target, GLuint buffer);
1191
[email protected]86093972010-03-11 00:13:561192 // Wrapper for glBindFramebuffer since we need to track the current targets.
1193 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1194
1195 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1196 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1197
[email protected]a93bb842010-02-16 23:03:471198 // Wrapper for glBindTexture since we need to track the current targets.
1199 void DoBindTexture(GLenum target, GLuint texture);
1200
[email protected]944b62f32012-09-27 02:20:461201 // Wrapper for glBindVertexArrayOES
1202 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571203 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461204
[email protected]8e3e0662010-08-23 18:46:301205 // Wrapper for glBlitFramebufferEXT.
1206 void DoBlitFramebufferEXT(
1207 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1208 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1209 GLbitfield mask, GLenum filter);
1210
[email protected]36cef8ce2010-03-16 07:34:451211 // Wrapper for glBufferData.
[email protected]0c86dbf2010-03-05 08:14:111212 void DoBufferData(
1213 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
1214
[email protected]36cef8ce2010-03-16 07:34:451215 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111216 void DoBufferSubData(
1217 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1218
[email protected]36cef8ce2010-03-16 07:34:451219 // Wrapper for glCheckFramebufferStatus
1220 GLenum DoCheckFramebufferStatus(GLenum target);
1221
[email protected]3a03a8f2011-03-19 00:51:271222 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081223 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271224
[email protected]88a61bf2012-10-27 13:00:421225 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421226 void DoDepthRangef(GLclampf znear, GLclampf zfar);
1227 void DoHint(GLenum target, GLenum mode);
[email protected]b04e24c2013-01-08 18:35:251228 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281229
[email protected]45bf5152010-02-12 00:11:311230 // Wrapper for glCompileShader.
1231 void DoCompileShader(GLuint shader);
1232
[email protected]269200b12010-11-18 22:53:061233 // Helper for DeleteSharedIdsCHROMIUM commands.
1234 void DoDeleteSharedIdsCHROMIUM(
1235 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101236
[email protected]ae51d192010-04-27 00:48:031237 // Wrapper for glDetachShader
1238 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1239
[email protected]3a2e7c7b2010-08-06 01:12:281240 // Wrapper for glDisable
1241 void DoDisable(GLenum cap);
1242
[email protected]07f54fcc2009-12-22 02:46:301243 // Wrapper for glDisableVertexAttribArray.
1244 void DoDisableVertexAttribArray(GLuint index);
1245
[email protected]60f22d32012-12-12 00:31:581246 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1247 // attachments.
1248 void DoDiscardFramebufferEXT(GLenum target,
1249 GLsizei numAttachments,
1250 const GLenum* attachments);
1251
[email protected]3a2e7c7b2010-08-06 01:12:281252 // Wrapper for glEnable
1253 void DoEnable(GLenum cap);
1254
[email protected]07f54fcc2009-12-22 02:46:301255 // Wrapper for glEnableVertexAttribArray.
1256 void DoEnableVertexAttribArray(GLuint index);
1257
[email protected]882ba1e22012-03-08 19:02:531258 // Wrapper for glFinish.
1259 void DoFinish();
1260
1261 // Wrapper for glFlush.
1262 void DoFlush();
1263
[email protected]36cef8ce2010-03-16 07:34:451264 // Wrapper for glFramebufferRenderbufffer.
1265 void DoFramebufferRenderbuffer(
1266 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1267 GLuint renderbuffer);
1268
1269 // Wrapper for glFramebufferTexture2D.
1270 void DoFramebufferTexture2D(
1271 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1272 GLint level);
1273
[email protected]a93bb842010-02-16 23:03:471274 // Wrapper for glGenerateMipmap
1275 void DoGenerateMipmap(GLenum target);
1276
[email protected]269200b12010-11-18 22:53:061277 // Helper for GenSharedIdsCHROMIUM commands.
1278 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101279 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1280
[email protected]b273e432010-04-12 17:23:581281 // Wrapper for DoGetBooleanv.
1282 void DoGetBooleanv(GLenum pname, GLboolean* params);
1283
1284 // Wrapper for DoGetFloatv.
1285 void DoGetFloatv(GLenum pname, GLfloat* params);
1286
[email protected]36cef8ce2010-03-16 07:34:451287 // Wrapper for glGetFramebufferAttachmentParameteriv.
1288 void DoGetFramebufferAttachmentParameteriv(
1289 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1290
[email protected]a0c3e972010-04-21 00:49:131291 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581292 void DoGetIntegerv(GLenum pname, GLint* params);
1293
[email protected]29a9eb52010-04-13 09:04:231294 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061295 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231296 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1297
[email protected]17cfbe0e2013-03-07 01:26:081298 // Wrapper for glGetBufferParameteriv.
1299 void DoGetBufferParameteriv(
1300 GLenum target, GLenum pname, GLint* params);
1301
[email protected]a0c3e972010-04-21 00:49:131302 // Wrapper for glGetProgramiv.
1303 void DoGetProgramiv(
1304 GLuint program_id, GLenum pname, GLint* params);
1305
[email protected]36cef8ce2010-03-16 07:34:451306 // Wrapper for glRenderbufferParameteriv.
1307 void DoGetRenderbufferParameteriv(
1308 GLenum target, GLenum pname, GLint* params);
1309
[email protected]ddd968b82010-03-02 00:44:291310 // Wrapper for glGetShaderiv
1311 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1312
[email protected]b1122982010-05-17 23:04:241313 // Wrappers for glGetVertexAttrib.
1314 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1315 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1316
[email protected]1958e0e2010-04-22 05:17:151317 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241318 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151319 bool DoIsBuffer(GLuint client_id);
1320 bool DoIsFramebuffer(GLuint client_id);
1321 bool DoIsProgram(GLuint client_id);
1322 bool DoIsRenderbuffer(GLuint client_id);
1323 bool DoIsShader(GLuint client_id);
1324 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461325 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151326
[email protected]07f54fcc2009-12-22 02:46:301327 // Wrapper for glLinkProgram
1328 void DoLinkProgram(GLuint program);
1329
[email protected]269200b12010-11-18 22:53:061330 // Helper for RegisterSharedIdsCHROMIUM.
1331 void DoRegisterSharedIdsCHROMIUM(
1332 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101333
[email protected]36cef8ce2010-03-16 07:34:451334 // Wrapper for glRenderbufferStorage.
1335 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031336 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451337
[email protected]8e3e0662010-08-23 18:46:301338 // Wrapper for glRenderbufferStorageMultisampleEXT.
1339 void DoRenderbufferStorageMultisample(
1340 GLenum target, GLsizei samples, GLenum internalformat,
1341 GLsizei width, GLsizei height);
1342
[email protected]b273e432010-04-12 17:23:581343 // Wrapper for glReleaseShaderCompiler.
1344 void DoReleaseShaderCompiler() { }
1345
[email protected]3916c97e2010-02-25 03:20:501346 // Wrappers for glTexParameter functions.
1347 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1348 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1349 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1350 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1351
1352 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1353 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121354 void DoUniform1i(GLint fake_location, GLint v0);
1355 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1356 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1357 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1358 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101359
1360 // Wrappers for glUniformfv because some drivers don't correctly accept
1361 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121362 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1363 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1364 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1365 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501366
[email protected]43c2f1f2011-03-25 18:35:361367 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121368 GLint fake_location, GLsizei count, GLboolean transpose,
1369 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361370 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121371 GLint fake_location, GLsizei count, GLboolean transpose,
1372 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361373 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121374 GLint fake_location, GLsizei count, GLboolean transpose,
1375 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361376
[email protected]af6380962012-11-29 23:24:131377 bool SetVertexAttribValue(
1378 const char* function_name, GLuint index, const GLfloat* value);
1379
[email protected]b1122982010-05-17 23:04:241380 // Wrappers for glVertexAttrib??
1381 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1382 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1383 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1384 void DoVertexAttrib4f(
1385 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1386 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1387 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1388 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1389 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1390
[email protected]43410e92012-04-20 17:06:281391 // Wrapper for glViewport
1392 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1393
[email protected]07f54fcc2009-12-22 02:46:301394 // Wrapper for glUseProgram
1395 void DoUseProgram(GLuint program);
1396
[email protected]ae51d192010-04-27 00:48:031397 // Wrapper for glValidateProgram.
1398 void DoValidateProgram(GLuint program_client_id);
1399
[email protected]d2a0e1a2012-08-12 02:25:011400 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1401 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1402 void DoPopGroupMarkerEXT(void);
1403
[email protected]4e8a5b122010-05-08 22:00:101404 // Gets the number of values that will be returned by glGetXXX. Returns
1405 // false if pname is unknown.
1406 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1407
[email protected]07f54fcc2009-12-22 02:46:301408 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431409 bool IsDrawValid(
1410 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301411
[email protected]c13e1da62011-09-09 21:48:301412 // Returns true if successful, simulated will be true if attrib0 was
1413 // simulated.
[email protected]c6aef902012-02-14 03:31:421414 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431415 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]43410e92012-04-20 17:06:281416 void RestoreStateForAttrib(GLuint attrib);
[email protected]b1122982010-05-17 23:04:241417
[email protected]ef526492010-06-02 23:12:251418 // Returns true if textures were set.
1419 bool SetBlackTextureForNonRenderableTextures();
[email protected]3916c97e2010-02-25 03:20:501420 void RestoreStateForNonRenderableTextures();
1421
[email protected]8fbedc02010-11-18 18:43:401422 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421423 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431424 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421425 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401426 void RestoreStateForSimulatedFixedAttribs();
1427
[email protected]c6aef902012-02-14 03:31:421428 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1429 // cases (primcount is 0 for non-instanced).
1430 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431431 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421432 bool instanced, GLenum mode, GLint first, GLsizei count,
1433 GLsizei primcount);
1434 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431435 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421436 bool instanced, GLenum mode, GLsizei count, GLenum type,
1437 int32 offset, GLsizei primcount);
1438
[email protected]07f54fcc2009-12-22 02:46:301439 // Gets the buffer id for a given target.
[email protected]16ccec12013-02-28 03:40:211440 Buffer* GetBufferInfoForTarget(GLenum target) {
[email protected]07f54fcc2009-12-22 02:46:301441 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER);
[email protected]944b62f32012-09-27 02:20:461442 if (target == GL_ARRAY_BUFFER) {
[email protected]e259eb412012-10-13 05:47:241443 return state_.bound_array_buffer;
[email protected]944b62f32012-09-27 02:20:461444 } else {
[email protected]e259eb412012-10-13 05:47:241445 return state_.vertex_attrib_manager->element_array_buffer();
[email protected]944b62f32012-09-27 02:20:461446 }
[email protected]07f54fcc2009-12-22 02:46:301447 }
1448
[email protected]a93bb842010-02-16 23:03:471449 // Gets the texture id for a given target.
[email protected]ed9f9cd2013-02-27 21:12:351450 Texture* GetTextureInfoForTarget(GLenum target) {
[email protected]e259eb412012-10-13 05:47:241451 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]02965c22013-03-09 02:40:071452 Texture* texture = NULL;
[email protected]a93bb842010-02-16 23:03:471453 switch (target) {
1454 case GL_TEXTURE_2D:
[email protected]02965c22013-03-09 02:40:071455 texture = unit.bound_texture_2d;
[email protected]3916c97e2010-02-25 03:20:501456 break;
[email protected]a93bb842010-02-16 23:03:471457 case GL_TEXTURE_CUBE_MAP:
1458 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1459 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1460 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1461 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1462 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1463 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
[email protected]02965c22013-03-09 02:40:071464 texture = unit.bound_texture_cube_map;
[email protected]3916c97e2010-02-25 03:20:501465 break;
[email protected]61eeb33f2011-07-26 15:30:311466 case GL_TEXTURE_EXTERNAL_OES:
[email protected]02965c22013-03-09 02:40:071467 texture = unit.bound_texture_external_oes;
[email protected]61eeb33f2011-07-26 15:30:311468 break;
[email protected]e51bdf32011-11-23 22:21:461469 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]02965c22013-03-09 02:40:071470 texture = unit.bound_texture_rectangle_arb;
[email protected]e51bdf32011-11-23 22:21:461471 break;
[email protected]a93bb842010-02-16 23:03:471472 default:
1473 NOTREACHED();
[email protected]3916c97e2010-02-25 03:20:501474 return NULL;
[email protected]a93bb842010-02-16 23:03:471475 }
[email protected]02965c22013-03-09 02:40:071476 return texture;
[email protected]a93bb842010-02-16 23:03:471477 }
1478
[email protected]ed9f9cd2013-02-27 21:12:351479 Texture* GetTextureInfoForTargetUnlessDefault(
[email protected]09d50362012-10-18 20:54:371480 GLenum target) {
[email protected]02965c22013-03-09 02:40:071481 Texture* texture = GetTextureInfoForTarget(target);
1482 if (!texture)
[email protected]09d50362012-10-18 20:54:371483 return NULL;
[email protected]02965c22013-03-09 02:40:071484 if (texture == texture_manager()->GetDefaultTextureInfo(target))
[email protected]09d50362012-10-18 20:54:371485 return NULL;
[email protected]02965c22013-03-09 02:40:071486 return texture;
[email protected]09d50362012-10-18 20:54:371487 }
1488
[email protected]61eeb33f2011-07-26 15:30:311489 GLenum GetBindTargetForSamplerType(GLenum type) {
1490 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461491 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1492 switch (type) {
1493 case GL_SAMPLER_2D:
1494 return GL_TEXTURE_2D;
1495 case GL_SAMPLER_CUBE:
1496 return GL_TEXTURE_CUBE_MAP;
1497 case GL_SAMPLER_EXTERNAL_OES:
1498 return GL_TEXTURE_EXTERNAL_OES;
1499 case GL_SAMPLER_2D_RECT_ARB:
1500 return GL_TEXTURE_RECTANGLE_ARB;
1501 }
1502
1503 NOTREACHED();
1504 return 0;
[email protected]61eeb33f2011-07-26 15:30:311505 }
1506
[email protected]8e3e0662010-08-23 18:46:301507 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061508 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1509 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301510 switch (target) {
1511 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451512 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]4d8f0dd2013-03-09 14:37:061513 framebuffer = state_.bound_draw_framebuffer;
[email protected]8e3e0662010-08-23 18:46:301514 break;
[email protected]ebfb73c2012-08-15 02:37:451515 case GL_READ_FRAMEBUFFER_EXT:
[email protected]4d8f0dd2013-03-09 14:37:061516 framebuffer = state_.bound_read_framebuffer;
[email protected]8e3e0662010-08-23 18:46:301517 break;
1518 default:
1519 NOTREACHED();
1520 break;
1521 }
[email protected]4d8f0dd2013-03-09 14:37:061522 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301523 }
1524
[email protected]ed9f9cd2013-02-27 21:12:351525 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201526 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271527 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201528 switch (target) {
1529 case GL_RENDERBUFFER:
[email protected]ee2a79c32013-03-10 03:50:271530 renderbuffer = state_.bound_renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201531 break;
1532 default:
1533 NOTREACHED();
1534 break;
1535 }
[email protected]ee2a79c32013-03-10 03:50:271536 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201537 }
1538
[email protected]f7b85372010-02-03 01:11:371539 // Validates the program and location for a glGetUniform call and returns
1540 // a SizeResult setup to receive the result. Returns true if glGetUniform
1541 // should be called.
1542 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121543 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371544 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121545 error::Error* error, GLint* real_location, GLuint* service_id,
1546 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371547
[email protected]1078f912011-12-23 13:12:141548 // Computes the estimated memory used for the backbuffer and passes it to
1549 // the tracing system.
[email protected]260ddc4e2012-06-28 00:01:531550 size_t GetBackbufferMemoryTotal();
[email protected]1078f912011-12-23 13:12:141551
[email protected]a10b4a02012-11-26 23:09:501552 virtual bool WasContextLost() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091553 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431554
[email protected]e51bdf32011-11-23 22:21:461555#if defined(OS_MACOSX)
1556 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1557#endif
1558
[email protected]81375742012-06-08 00:04:001559 // Validates the combination of texture parameters. For example validates that
1560 // for a given format the specific type, level and targets are valid.
1561 // Synthesizes the correct GL error if invalid. Returns true if valid.
1562 bool ValidateTextureParameters(
1563 const char* function_name,
1564 GLenum target, GLenum format, GLenum type, GLint level);
1565
[email protected]ad84a3a2012-06-08 21:42:431566 bool ValidateCompressedTexDimensions(
1567 const char* function_name,
1568 GLint level, GLsizei width, GLsizei height, GLenum format);
1569 bool ValidateCompressedTexFuncData(
1570 const char* function_name,
1571 GLsizei width, GLsizei height, GLenum format, size_t size);
1572 bool ValidateCompressedTexSubDimensions(
1573 const char* function_name,
1574 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1575 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351576 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431577
[email protected]ab09b612013-03-11 22:11:511578 void RenderWarning(const char* filename, int line, const std::string& msg);
1579 void PerformanceWarning(
1580 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011581
[email protected]62e155e2012-10-23 22:43:151582 const FeatureInfo::FeatureFlags& features() const {
1583 return feature_info_->feature_flags();
1584 }
1585
1586 const FeatureInfo::Workarounds& workarounds() const {
1587 return feature_info_->workarounds();
1588 }
1589
[email protected]a7266a92012-06-28 02:11:081590 bool ShouldDeferDraws() {
1591 return !offscreen_target_frame_buffer_.get() &&
[email protected]e259eb412012-10-13 05:47:241592 state_.bound_draw_framebuffer == NULL &&
[email protected]a7266a92012-06-28 02:11:081593 surface_->DeferDraws();
1594 }
1595
[email protected]09e17272012-11-30 10:30:441596 bool ShouldDeferReads() {
1597 return !offscreen_target_frame_buffer_.get() &&
1598 state_.bound_read_framebuffer == NULL &&
1599 surface_->DeferDraws();
1600 }
1601
[email protected]df37b9932013-03-08 05:21:421602 void ForceCompileShaderIfPending(Shader* shader);
[email protected]c447acd2012-07-23 23:48:411603
[email protected]96449d2c2009-11-25 00:01:321604 // Generate a member function prototype for each command in an automated and
1605 // typesafe way.
1606 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141607 Error Handle ## name( \
[email protected]ed9f9cd2013-02-27 21:12:351608 uint32 immediate_data_size, \
1609 const cmds::name& args); \
[email protected]96449d2c2009-11-25 00:01:321610
1611 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1612
1613 #undef GLES2_CMD_OP
1614
[email protected]2f2d7042010-04-14 21:45:581615 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381616 scoped_refptr<gfx::GLSurface> surface_;
1617 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021618
[email protected]a3ded6d2010-10-19 06:44:391619 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351620 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391621
[email protected]1d82e822013-04-10 21:32:321622 DebugMarkerManager debug_marker_manager_;
1623 Logger logger_;
1624
[email protected]e259eb412012-10-13 05:47:241625 // All the state for this context.
1626 ContextState state_;
1627
[email protected]6217d392010-03-25 22:08:351628 // A parent decoder can access this decoders saved offscreen frame buffer.
1629 // The parent pointer is reset if the parent is destroyed.
1630 base::WeakPtr<GLES2DecoderImpl> parent_;
1631
[email protected]34ff8b0c2010-10-01 20:06:021632 // Current width and height of the offscreen frame buffer.
1633 gfx::Size offscreen_size_;
1634
[email protected]96449d2c2009-11-25 00:01:321635 // Util to help with GL.
1636 GLES2Util util_;
1637
[email protected]43410e92012-04-20 17:06:281638 // unpack flip y as last set by glPixelStorei
1639 bool unpack_flip_y_;
1640
[email protected]6c75c712012-06-19 15:43:171641 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281642 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171643 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281644
[email protected]944b62f32012-09-27 02:20:461645 // Default vertex attribs manager, used when no VAOs are bound.
[email protected]ed9f9cd2013-02-27 21:12:351646 scoped_refptr<VertexAttribManager> default_vertex_attrib_manager_;
[email protected]07f54fcc2009-12-22 02:46:301647
[email protected]b1122982010-05-17 23:04:241648 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1649 GLuint attrib_0_buffer_id_;
1650
1651 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131652 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241653
[email protected]fc753442011-02-04 19:49:491654 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1655 bool attrib_0_buffer_matches_value_;
1656
[email protected]b1122982010-05-17 23:04:241657 // The size of attrib 0.
1658 GLsizei attrib_0_size_;
1659
[email protected]8fbedc02010-11-18 18:43:401660 // The buffer used to simulate GL_FIXED attribs.
1661 GLuint fixed_attrib_buffer_id_;
1662
1663 // The size of fiixed attrib buffer.
1664 GLsizei fixed_attrib_buffer_size_;
1665
[email protected]3a2e7c7b2010-08-06 01:12:281666 // state saved for clearing so we can clear render buffers and then
1667 // restore to these values.
[email protected]88a61bf2012-10-27 13:00:421668 bool clear_state_dirty_;
[email protected]3a2e7c7b2010-08-06 01:12:281669
[email protected]b9363b22010-06-09 22:06:151670 // The offscreen frame buffer that the client renders to. With EGL, the
1671 // depth and stencil buffers are separate. With regular GL there is a single
1672 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1673 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351674 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1675 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1676 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1677 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1678 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021679 GLenum offscreen_target_color_format_;
1680 GLenum offscreen_target_depth_format_;
1681 GLenum offscreen_target_stencil_format_;
1682 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561683 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351684
[email protected]de26b3c2011-08-03 21:54:271685 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351686 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1687 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
1688 scoped_refptr<Texture>
1689 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271690
1691 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351692 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1693 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051694 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351695
[email protected]882ba1e22012-03-08 19:02:531696 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531697
[email protected]944b62f32012-09-27 02:20:461698 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1699
[email protected]9d37f062011-11-22 01:24:521700 base::Callback<void(gfx::Size)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001701
[email protected]840a7e462013-02-27 01:29:511702 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481703
[email protected]e3932abb2013-03-13 00:01:371704 ShaderCacheCallback shader_cache_callback_;
1705
[email protected]b0af4f52011-09-28 22:04:421706 StreamTextureManager* stream_texture_manager_;
[email protected]32145a92012-12-17 09:01:591707 scoped_ptr<gfx::AsyncPixelTransferDelegate> async_pixel_transfer_delegate_;
[email protected]b0af4f52011-09-28 22:04:421708
[email protected]32fe9aa2011-01-21 23:47:131709 // The format of the back buffer_
1710 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461711 bool back_buffer_has_depth_;
1712 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131713
[email protected]60f22d32012-12-12 00:31:581714 // Backbuffer attachments that are currently undefined.
1715 uint32 backbuffer_needs_clear_bits_;
1716
[email protected]473c01ccb2011-06-07 01:33:301717 bool teximage2d_faster_than_texsubimage2d_;
[email protected]473c01ccb2011-06-07 01:33:301718
[email protected]a3a93e7b2010-08-28 00:48:561719 // The current decoder error.
1720 error::Error current_decoder_error_;
1721
[email protected]b1d2dcb2010-05-17 19:24:181722 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041723 scoped_refptr<ShaderTranslator> vertex_translator_;
1724 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181725
[email protected]e82fb792011-09-22 00:33:291726 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411727
[email protected]915a59a12010-09-30 21:29:111728 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051729 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351730 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051731
[email protected]b493ee622011-04-13 23:52:001732 // This indicates all the following texSubImage2D calls that are part of the
1733 // failed texImage2D call should be ignored.
1734 bool tex_image_2d_failed_;
1735
[email protected]65225772011-05-12 21:10:241736 int frame_number_;
1737
[email protected]706b69f2012-07-27 04:59:301738 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431739 GLenum reset_status_;
1740
[email protected]f0d74742011-10-03 16:31:041741 // These flags are used to override the state of the shared feature_info_
1742 // member. Because the same FeatureInfo instance may be shared among many
1743 // contexts, the assumptions on the availablity of extensions in WebGL
1744 // contexts may be broken. These flags override the shared state to preserve
1745 // WebGL semantics.
1746 bool force_webgl_glsl_validation_;
1747 bool derivatives_explicitly_enabled_;
1748
[email protected]062c38b2012-01-18 03:25:101749 bool compile_shader_always_succeeds_;
1750
[email protected]cae20172012-12-07 00:06:191751 // Log extra info.
1752 bool service_logging_;
1753
[email protected]e51bdf32011-11-23 22:21:461754#if defined(OS_MACOSX)
1755 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap;
1756 TextureToIOSurfaceMap texture_to_io_surface_map_;
1757#endif
1758
[email protected]c826d732012-02-09 04:40:261759 typedef std::vector<GLES2DecoderImpl*> ChildList;
1760 ChildList children_;
1761
[email protected]43410e92012-04-20 17:06:281762 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1763
[email protected]1868a342012-11-07 15:56:021764 // Cached values of the currently assigned viewport dimensions.
1765 GLsizei viewport_max_width_;
1766 GLsizei viewport_max_height_;
1767
[email protected]63b465922012-09-06 02:04:521768 // Command buffer stats.
1769 int texture_upload_count_;
1770 base::TimeDelta total_texture_upload_time_;
1771 base::TimeDelta total_processing_commands_time_;
1772
[email protected]fb97b662013-02-20 23:02:141773 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]94307712012-11-16 23:26:111774
[email protected]96449d2c2009-11-25 00:01:321775 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1776};
1777
[email protected]ab09b612013-03-11 22:11:511778ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
1779 const char* function_name, GLES2DecoderImpl* decoder)
1780 : function_name_(function_name),
1781 decoder_(decoder) {
[email protected]d3eba342013-04-18 21:11:501782 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder_->GetErrorState(),
1783 function_name_);
[email protected]6217d392010-03-25 22:08:351784}
1785
1786ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]d3eba342013-04-18 21:11:501787 ERRORSTATE_CLEAR_REAL_GL_ERRORS(decoder_->GetErrorState(), function_name_);
[email protected]6217d392010-03-25 22:08:351788}
1789
1790ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder,
1791 GLuint id)
1792 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511793 ScopedGLErrorSuppressor suppressor(
1794 "ScopedTexture2DBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351795
1796 // TODO(apatrick): Check if there are any other states that need to be reset
1797 // before binding a new texture.
1798 glActiveTexture(GL_TEXTURE0);
1799 glBindTexture(GL_TEXTURE_2D, id);
1800}
1801
1802ScopedTexture2DBinder::~ScopedTexture2DBinder() {
[email protected]ab09b612013-03-11 22:11:511803 ScopedGLErrorSuppressor suppressor(
1804 "ScopedTexture2DBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301805 decoder_->RestoreCurrentTexture2DBindings();
[email protected]6217d392010-03-25 22:08:351806}
1807
1808ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder,
1809 GLuint id)
1810 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511811 ScopedGLErrorSuppressor suppressor(
1812 "ScopedRenderBufferBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351813 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1814}
1815
1816ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511817 ScopedGLErrorSuppressor suppressor(
1818 "ScopedRenderBufferBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301819 decoder_->RestoreCurrentRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351820}
1821
1822ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1823 GLuint id)
1824 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511825 ScopedGLErrorSuppressor suppressor(
1826 "ScopedFrameBufferBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351827 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451828 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351829}
1830
1831ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511832 ScopedGLErrorSuppressor suppressor(
1833 "ScopedFrameBufferBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301834 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351835}
1836
[email protected]34ff8b0c2010-10-01 20:06:021837ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271838 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521839 : decoder_(decoder) {
[email protected]34ff8b0c2010-10-01 20:06:021840 resolve_and_bind_ = (decoder_->offscreen_target_frame_buffer_.get() &&
1841 decoder_->IsOffscreenBufferMultisampled() &&
[email protected]e259eb412012-10-13 05:47:241842 (!decoder_->state_.bound_read_framebuffer.get() ||
[email protected]c0701082011-04-20 00:34:521843 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021844 if (!resolve_and_bind_)
1845 return;
1846
[email protected]ab09b612013-03-11 22:11:511847 ScopedGLErrorSuppressor suppressor(
1848 "ScopedResolvedFrameBufferBinder::ctor", decoder_);
[email protected]34ff8b0c2010-10-01 20:06:021849 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1850 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271851 GLuint targetid;
1852 if (internal) {
1853 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1854 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351855 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271856 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351857 decoder_->offscreen_resolved_color_texture_.reset(
1858 new BackTexture(decoder_));
[email protected]de26b3c2011-08-03 21:54:271859 decoder_->offscreen_resolved_color_texture_->Create();
1860
1861 DCHECK(decoder_->offscreen_saved_color_format_);
1862 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091863 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1864 false);
[email protected]de26b3c2011-08-03 21:54:271865 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1866 decoder_->offscreen_resolved_color_texture_.get());
1867 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1868 GL_FRAMEBUFFER_COMPLETE) {
1869 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1870 << "because offscreen resolved FBO was incomplete.";
1871 return;
1872 }
1873 }
1874 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1875 } else {
1876 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1877 }
1878 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021879 const int width = decoder_->offscreen_size_.width();
1880 const int height = decoder_->offscreen_size_.height();
[email protected]8c3e68782010-10-27 16:41:181881 glDisable(GL_SCISSOR_TEST);
[email protected]57edfdad2012-02-07 04:57:151882 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021883 glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height,
1884 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1885 } else {
1886 glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height,
1887 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1888 }
[email protected]de26b3c2011-08-03 21:54:271889 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021890}
1891
1892ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1893 if (!resolve_and_bind_)
1894 return;
1895
[email protected]ab09b612013-03-11 22:11:511896 ScopedGLErrorSuppressor suppressor(
1897 "ScopedResolvedFrameBufferBinder::dtor", decoder_);
[email protected]34ff8b0c2010-10-01 20:06:021898 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:221899 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]8c3e68782010-10-27 16:41:181900 glEnable(GL_SCISSOR_TEST);
1901 }
[email protected]34ff8b0c2010-10-01 20:06:021902}
1903
[email protected]63b465922012-09-06 02:04:521904ScopedTextureUploadTimer::ScopedTextureUploadTimer(GLES2DecoderImpl* decoder)
1905 : decoder_(decoder),
1906 begin_time_(base::TimeTicks::HighResNow()) {
1907}
1908
1909ScopedTextureUploadTimer::~ScopedTextureUploadTimer() {
1910 decoder_->texture_upload_count_++;
1911 decoder_->total_texture_upload_time_ +=
1912 base::TimeTicks::HighResNow() - begin_time_;
1913}
1914
[email protected]ed9f9cd2013-02-27 21:12:351915BackTexture::BackTexture(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:351916 : decoder_(decoder),
[email protected]7989c9e2013-01-23 06:39:261917 memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged),
[email protected]68e81a4a62012-12-13 01:16:481918 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251919 id_(0) {
[email protected]6217d392010-03-25 22:08:351920}
1921
[email protected]ed9f9cd2013-02-27 21:12:351922BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:351923 // This does not destroy the render texture because that would require that
1924 // the associated GL context was current. Just check that it was explicitly
1925 // destroyed.
1926 DCHECK_EQ(id_, 0u);
1927}
1928
[email protected]ed9f9cd2013-02-27 21:12:351929void BackTexture::Create() {
[email protected]ab09b612013-03-11 22:11:511930 ScopedGLErrorSuppressor suppressor("BackTexture::Create", decoder_);
[email protected]6217d392010-03-25 22:08:351931 Destroy();
1932 glGenTextures(1, &id_);
[email protected]3a4d0c52011-06-29 23:11:581933 ScopedTexture2DBinder binder(decoder_, id_);
1934 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1935 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1936 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1937 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:161938
1939 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
1940 // never called on an offscreen context, no data will ever be uploaded to the
1941 // saved offscreen color texture (it is deferred until to when SwapBuffers
1942 // is called). My idea is that some nvidia drivers might have a bug where
1943 // deleting a texture that has never been populated might cause a
1944 // crash.
1945 glTexImage2D(
1946 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:481947
1948 bytes_allocated_ = 16u * 16u * 4u;
1949 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:351950}
1951
[email protected]ed9f9cd2013-02-27 21:12:351952bool BackTexture::AllocateStorage(
1953 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:351954 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:511955 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage", decoder_);
[email protected]6217d392010-03-25 22:08:351956 ScopedTexture2DBinder binder(decoder_, id_);
[email protected]678a73f2012-12-19 19:22:091957 uint32 image_size = 0;
1958 GLES2Util::ComputeImageDataSizes(
1959 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
1960 NULL, NULL);
1961
[email protected]7989c9e2013-01-23 06:39:261962 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
1963 return false;
1964 }
1965
[email protected]40d90a22013-04-09 03:39:551966 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:091967 if (zero) {
1968 zero_data.reset(new char[image_size]);
1969 memset(zero_data.get(), 0, image_size);
1970 }
[email protected]6217d392010-03-25 22:08:351971
[email protected]f0e6a34f2012-01-04 20:53:401972 WrappedTexImage2D(GL_TEXTURE_2D,
1973 0, // mip level
1974 format,
1975 size.width(),
1976 size.height(),
1977 0, // border
1978 format,
1979 GL_UNSIGNED_BYTE,
[email protected]678a73f2012-12-19 19:22:091980 zero_data.get());
[email protected]6217d392010-03-25 22:08:351981
[email protected]d37231fa2010-04-09 21:16:021982 size_ = size;
1983
[email protected]1078f912011-12-23 13:12:141984 bool success = glGetError() == GL_NO_ERROR;
1985 if (success) {
[email protected]68e81a4a62012-12-13 01:16:481986 memory_tracker_.TrackMemFree(bytes_allocated_);
1987 bytes_allocated_ = image_size;
1988 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:141989 }
1990 return success;
[email protected]6217d392010-03-25 22:08:351991}
1992
[email protected]ed9f9cd2013-02-27 21:12:351993void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:351994 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:511995 ScopedGLErrorSuppressor suppressor("BackTexture::Copy", decoder_);
[email protected]6217d392010-03-25 22:08:351996 ScopedTexture2DBinder binder(decoder_, id_);
1997 glCopyTexImage2D(GL_TEXTURE_2D,
1998 0, // level
[email protected]3a4d0c52011-06-29 23:11:581999 format,
[email protected]6217d392010-03-25 22:08:352000 0, 0,
2001 size.width(),
2002 size.height(),
2003 0); // border
2004}
2005
[email protected]ed9f9cd2013-02-27 21:12:352006void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:352007 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:512008 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:352009 glDeleteTextures(1, &id_);
2010 id_ = 0;
2011 }
[email protected]68e81a4a62012-12-13 01:16:482012 memory_tracker_.TrackMemFree(bytes_allocated_);
2013 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352014}
2015
[email protected]ed9f9cd2013-02-27 21:12:352016void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:052017 id_ = 0;
2018}
2019
[email protected]ed9f9cd2013-02-27 21:12:352020BackRenderbuffer::BackRenderbuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352021 : decoder_(decoder),
[email protected]7989c9e2013-01-23 06:39:262022 memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged),
[email protected]68e81a4a62012-12-13 01:16:482023 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252024 id_(0) {
[email protected]6217d392010-03-25 22:08:352025}
2026
[email protected]ed9f9cd2013-02-27 21:12:352027BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352028 // This does not destroy the render buffer because that would require that
2029 // the associated GL context was current. Just check that it was explicitly
2030 // destroyed.
2031 DCHECK_EQ(id_, 0u);
2032}
2033
[email protected]ed9f9cd2013-02-27 21:12:352034void BackRenderbuffer::Create() {
[email protected]ab09b612013-03-11 22:11:512035 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create", decoder_);
[email protected]6217d392010-03-25 22:08:352036 Destroy();
2037 glGenRenderbuffersEXT(1, &id_);
2038}
2039
[email protected]ed9f9cd2013-02-27 21:12:352040bool BackRenderbuffer::AllocateStorage(const gfx::Size& size, GLenum format,
2041 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512042 ScopedGLErrorSuppressor suppressor(
2043 "BackRenderbuffer::AllocateStorage", decoder_);
[email protected]6217d392010-03-25 22:08:352044 ScopedRenderBufferBinder binder(decoder_, id_);
[email protected]7989c9e2013-01-23 06:39:262045
2046 uint32 estimated_size = 0;
2047 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
2048 size.width(), size.height(), samples, format, &estimated_size)) {
2049 return false;
2050 }
2051
2052 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2053 return false;
2054 }
2055
[email protected]34ff8b0c2010-10-01 20:06:022056 if (samples <= 1) {
2057 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2058 format,
2059 size.width(),
2060 size.height());
2061 } else {
[email protected]57edfdad2012-02-07 04:57:152062 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:022063 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER,
2064 samples,
2065 format,
2066 size.width(),
2067 size.height());
2068 } else {
2069 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
2070 samples,
2071 format,
2072 size.width(),
2073 size.height());
2074 }
2075 }
[email protected]1078f912011-12-23 13:12:142076 bool success = glGetError() == GL_NO_ERROR;
2077 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482078 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262079 bytes_allocated_ = estimated_size;
[email protected]68e81a4a62012-12-13 01:16:482080 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142081 }
2082 return success;
[email protected]6217d392010-03-25 22:08:352083}
2084
[email protected]ed9f9cd2013-02-27 21:12:352085void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352086 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:512087 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:352088 glDeleteRenderbuffersEXT(1, &id_);
2089 id_ = 0;
2090 }
[email protected]68e81a4a62012-12-13 01:16:482091 memory_tracker_.TrackMemFree(bytes_allocated_);
2092 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352093}
2094
[email protected]ed9f9cd2013-02-27 21:12:352095void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052096 id_ = 0;
2097}
2098
[email protected]ed9f9cd2013-02-27 21:12:352099BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352100 : decoder_(decoder),
2101 id_(0) {
2102}
2103
[email protected]ed9f9cd2013-02-27 21:12:352104BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352105 // This does not destroy the frame buffer because that would require that
2106 // the associated GL context was current. Just check that it was explicitly
2107 // destroyed.
2108 DCHECK_EQ(id_, 0u);
2109}
2110
[email protected]ed9f9cd2013-02-27 21:12:352111void BackFramebuffer::Create() {
[email protected]ab09b612013-03-11 22:11:512112 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create", decoder_);
[email protected]6217d392010-03-25 22:08:352113 Destroy();
2114 glGenFramebuffersEXT(1, &id_);
2115}
2116
[email protected]ed9f9cd2013-02-27 21:12:352117void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352118 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512119 ScopedGLErrorSuppressor suppressor(
2120 "BackFramebuffer::AttachRenderTexture", decoder_);
[email protected]6217d392010-03-25 22:08:352121 ScopedFrameBufferBinder binder(decoder_, id_);
2122 GLuint attach_id = texture ? texture->id() : 0;
2123 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2124 GL_COLOR_ATTACHMENT0,
2125 GL_TEXTURE_2D,
2126 attach_id,
2127 0);
2128}
2129
[email protected]ed9f9cd2013-02-27 21:12:352130void BackFramebuffer::AttachRenderBuffer(GLenum target,
2131 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352132 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512133 ScopedGLErrorSuppressor suppressor(
2134 "BackFramebuffer::AttachRenderBuffer", decoder_);
[email protected]6217d392010-03-25 22:08:352135 ScopedFrameBufferBinder binder(decoder_, id_);
2136 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2137 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152138 target,
[email protected]6217d392010-03-25 22:08:352139 GL_RENDERBUFFER,
2140 attach_id);
2141}
2142
[email protected]ed9f9cd2013-02-27 21:12:352143void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352144 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:512145 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:352146 glDeleteFramebuffersEXT(1, &id_);
2147 id_ = 0;
2148 }
2149}
2150
[email protected]ed9f9cd2013-02-27 21:12:352151void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052152 id_ = 0;
2153}
2154
[email protected]ed9f9cd2013-02-27 21:12:352155GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352156 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512157 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus", decoder_);
[email protected]6217d392010-03-25 22:08:352158 ScopedFrameBufferBinder binder(decoder_, id_);
2159 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2160}
2161
[email protected]aa7666122011-09-02 19:45:522162GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2163 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322164}
2165
[email protected]aa7666122011-09-02 19:45:522166GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392167 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572168 group_(group),
[email protected]1d82e822013-04-10 21:32:322169 logger_(&debug_marker_manager_),
[email protected]d3eba342013-04-18 21:11:502170 state_(group_->feature_info(), &logger_),
[email protected]43410e92012-04-20 17:06:282171 unpack_flip_y_(false),
2172 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172173 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242174 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492175 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242176 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402177 fixed_attrib_buffer_id_(0),
2178 fixed_attrib_buffer_size_(0),
[email protected]88a61bf2012-10-27 13:00:422179 clear_state_dirty_(true),
[email protected]34ff8b0c2010-10-01 20:06:022180 offscreen_target_color_format_(0),
2181 offscreen_target_depth_format_(0),
2182 offscreen_target_stencil_format_(0),
2183 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562184 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052185 offscreen_saved_color_format_(0),
[email protected]b0af4f52011-09-28 22:04:422186 stream_texture_manager_(NULL),
[email protected]32fe9aa2011-01-21 23:47:132187 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462188 back_buffer_has_depth_(false),
2189 back_buffer_has_stencil_(false),
[email protected]60f22d32012-12-12 00:31:582190 backbuffer_needs_clear_bits_(0),
[email protected]473c01ccb2011-06-07 01:33:302191 teximage2d_faster_than_texsubimage2d_(true),
[email protected]a3a93e7b2010-08-28 00:48:562192 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052193 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112194 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002195 feature_info_(group_->feature_info()),
[email protected]65225772011-05-12 21:10:242196 tex_image_2d_failed_(false),
[email protected]38d139d2011-07-14 00:38:432197 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302198 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512199 reset_status_(GL_NO_ERROR),
[email protected]f0d74742011-10-03 16:31:042200 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102201 derivatives_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282202 compile_shader_always_succeeds_(false),
[email protected]cae20172012-12-07 00:06:192203 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2204 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022205 viewport_max_width_(0),
2206 viewport_max_height_(0),
[email protected]63b465922012-09-06 02:04:522207 texture_upload_count_(0) {
[email protected]3b1ecc262011-08-03 22:49:572208 DCHECK(group);
2209
[email protected]b1122982010-05-17 23:04:242210 attrib_0_value_.v[0] = 0.0f;
2211 attrib_0_value_.v[1] = 0.0f;
2212 attrib_0_value_.v[2] = 0.0f;
2213 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152214
[email protected]c2f8c8402010-12-06 18:07:242215 // The shader translator is used for WebGL even when running on EGL
2216 // because additional restrictions are needed (like only enabling
2217 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562218 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2219 // the empty string to CompileShader and this is not a valid shader.
2220 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002221 CommandLine::ForCurrentProcess()->HasSwitch(
2222 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152223 use_shader_translator_ = false;
2224 }
[email protected]473c01ccb2011-06-07 01:33:302225
[email protected]a39370652012-09-25 21:52:132226 // TODO(gman): Consider setting this based on GPU and/or driver.
[email protected]473c01ccb2011-06-07 01:33:302227 if (IsAngle()) {
2228 teximage2d_faster_than_texsubimage2d_ = false;
[email protected]473c01ccb2011-06-07 01:33:302229 }
[email protected]96449d2c2009-11-25 00:01:322230}
2231
[email protected]80eb6b52012-01-19 00:14:412232GLES2DecoderImpl::~GLES2DecoderImpl() {
2233}
2234
[email protected]c410da802011-03-14 19:17:412235bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382236 const scoped_refptr<gfx::GLSurface>& surface,
2237 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232238 bool offscreen,
[email protected]c410da802011-03-14 19:17:412239 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292240 const DisallowedFeatures& disallowed_features,
[email protected]c410da802011-03-14 19:17:412241 const char* allowed_extensions,
[email protected]3c644d82011-06-20 19:58:242242 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322243 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382244 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302245 DCHECK(!context_.get());
2246
[email protected]55e136f2013-04-03 18:50:062247 set_initialized();
[email protected]fb97b662013-02-20 23:02:142248 gpu_tracer_ = GPUTracer::Create();
2249
[email protected]e844ae22012-01-14 03:36:262250 if (CommandLine::ForCurrentProcess()->HasSwitch(
2251 switches::kEnableGPUDebugging)) {
2252 set_debug(true);
2253 }
2254
[email protected]39ba4f02012-03-26 01:16:002255 if (CommandLine::ForCurrentProcess()->HasSwitch(
2256 switches::kEnableGPUCommandLogging)) {
2257 set_log_commands(true);
2258 }
2259
[email protected]062c38b2012-01-18 03:25:102260 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2261 switches::kCompileShaderAlwaysSucceeds);
2262
[email protected]f62a5ab2011-05-23 20:34:152263
[email protected]63c9b052012-05-17 18:27:382264 // Take ownership of the context and surface. The surface can be replaced with
2265 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382266 context_ = context;
[email protected]63c9b052012-05-17 18:27:382267 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182268
[email protected]c4485aad62012-12-17 10:19:092269 if (!group_->Initialize(this, disallowed_features, allowed_extensions)) {
[email protected]09ddb91f2011-04-14 23:16:222270 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392271 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422272 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382273 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032274 return false;
[email protected]a3ded6d2010-10-19 06:44:392275 }
[email protected]b64c24952012-04-19 03:20:272276 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282277
[email protected]e82fb792011-09-22 00:33:292278 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502279
[email protected]af6380962012-11-29 23:24:132280 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]944b62f32012-09-27 02:20:462281 default_vertex_attrib_manager_ = new VertexAttribManager();
2282 default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs());
2283
[email protected]ab4fd7282012-10-12 16:25:572284 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call
2285 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322286
[email protected]d6ca4792012-05-14 19:24:132287 query_manager_.reset(new QueryManager(this, feature_info_));
[email protected]944b62f32012-09-27 02:20:462288 vertex_array_manager_.reset(new VertexArrayManager());
[email protected]882ba1e22012-03-08 19:02:532289
[email protected]302ce6d2011-07-07 23:28:112290 util_.set_num_compressed_texture_formats(
2291 validators_->compressed_texture_format.GetValues().size());
2292
[email protected]1071e572011-02-09 20:00:122293 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2294 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2295 // OpenGL ES 2.0 does not have this issue.
2296 glEnableVertexAttribArray(0);
2297 }
[email protected]b1122982010-05-17 23:04:242298 glGenBuffersARB(1, &attrib_0_buffer_id_);
2299 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2300 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2301 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402302 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082303
[email protected]1868a342012-11-07 15:56:022304 state_.texture_units.resize(group_->max_texture_units());
2305 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492306 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312307 // We want the last bind to be 2D.
[email protected]02965c22013-03-09 02:40:072308 Texture* texture;
[email protected]62e155e2012-10-23 22:43:152309 if (features().oes_egl_image_external) {
[email protected]02965c22013-03-09 02:40:072310 texture = texture_manager()->GetDefaultTextureInfo(
2311 GL_TEXTURE_EXTERNAL_OES);
2312 state_.texture_units[tt].bound_texture_external_oes = texture;
2313 glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture->service_id());
[email protected]61eeb33f2011-07-26 15:30:312314 }
[email protected]62e155e2012-10-23 22:43:152315 if (features().arb_texture_rectangle) {
[email protected]02965c22013-03-09 02:40:072316 texture = texture_manager()->GetDefaultTextureInfo(
2317 GL_TEXTURE_RECTANGLE_ARB);
2318 state_.texture_units[tt].bound_texture_rectangle_arb = texture;
2319 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture->service_id());
[email protected]e51bdf32011-11-23 22:21:462320 }
[email protected]02965c22013-03-09 02:40:072321 texture = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2322 state_.texture_units[tt].bound_texture_cube_map = texture;
2323 glBindTexture(GL_TEXTURE_CUBE_MAP, texture->service_id());
2324 texture = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2325 state_.texture_units[tt].bound_texture_2d = texture;
2326 glBindTexture(GL_TEXTURE_2D, texture->service_id());
[email protected]1958e0e2010-04-22 05:17:152327 }
[email protected]00f893d2010-08-24 18:55:492328 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502329 CHECK_GL_ERROR();
2330
[email protected]297ca1c2011-06-20 23:08:462331 ContextCreationAttribParser attrib_parser;
2332 if (!attrib_parser.Parse(attribs))
2333 return false;
[email protected]41c56362011-06-14 16:47:432334
[email protected]297ca1c2011-06-20 23:08:462335 // These are NOT if the back buffer has these proprorties. They are
2336 // if we want the command buffer to enforce them regardless of what
2337 // the real backbuffer is assuming the real back buffer gives us more than
2338 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2339 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2340 // can't do anything about that.
2341
2342 GLint v = 0;
2343 glGetIntegerv(GL_ALPHA_BITS, &v);
2344 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2345 // user requested RGB then RGB. If the user did not specify a preference than
2346 // use whatever we were given. Same for DEPTH and STENCIL.
2347 back_buffer_color_format_ =
2348 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2349 glGetIntegerv(GL_DEPTH_BITS, &v);
2350 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2351 glGetIntegerv(GL_STENCIL_BITS, &v);
2352 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
2353
[email protected]069944672012-04-25 20:52:232354 if (offscreen) {
[email protected]34ff8b0c2010-10-01 20:06:022355 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
[email protected]b0609652012-12-14 07:24:542356 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022357 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432358 // max_sample_count must be initialized to a sane value. If
2359 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2360 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022361 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2362 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2363 max_sample_count);
2364 } else {
2365 offscreen_target_samples_ = 1;
2366 }
[email protected]8a61d872012-01-20 12:43:562367 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
[email protected]34ff8b0c2010-10-01 20:06:022368
2369 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2370 const bool rgb8_supported =
2371 context_->HasExtension("GL_OES_rgb8_rgba8");
2372 // The only available default render buffer formats in GLES2 have very
2373 // little precision. Don't enable multisampling unless 8-bit render
2374 // buffer formats are available--instead fall back to 8-bit textures.
2375 if (rgb8_supported && offscreen_target_samples_ > 1) {
2376 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2377 GL_RGBA8 : GL_RGB8;
2378 } else {
2379 offscreen_target_samples_ = 1;
2380 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2381 GL_RGBA : GL_RGB;
2382 }
2383
2384 // ANGLE only supports packed depth/stencil formats, so use it if it is
2385 // available.
2386 const bool depth24_stencil8_supported =
2387 context_->HasExtension("GL_OES_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272388 VLOG(1) << "GL_OES_packed_depth_stencil "
2389 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]71ee3642010-10-14 18:08:002390 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2391 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022392 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2393 offscreen_target_stencil_format_ = 0;
2394 } else {
2395 // It may be the case that this depth/stencil combination is not
2396 // supported, but this will be checked later by CheckFramebufferStatus.
2397 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2398 GL_DEPTH_COMPONENT16 : 0;
2399 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2400 GL_STENCIL_INDEX8 : 0;
2401 }
2402 } else {
2403 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2404 GL_RGBA : GL_RGB;
2405
2406 // If depth is requested at all, use the packed depth stencil format if
2407 // it's available, as some desktop GL drivers don't support any non-packed
2408 // formats for depth attachments.
2409 const bool depth24_stencil8_supported =
2410 context_->HasExtension("GL_EXT_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272411 VLOG(1) << "GL_EXT_packed_depth_stencil "
2412 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022413
[email protected]71ee3642010-10-14 18:08:002414 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2415 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022416 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2417 offscreen_target_stencil_format_ = 0;
2418 } else {
2419 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2420 GL_DEPTH_COMPONENT : 0;
2421 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2422 GL_STENCIL_INDEX : 0;
2423 }
2424 }
2425
[email protected]97872062010-11-03 19:07:052426 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2427 GL_RGBA : GL_RGB;
2428
[email protected]6217d392010-03-25 22:08:352429 // Create the target frame buffer. This is the one that the client renders
2430 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352431 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352432 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022433 // Due to GLES2 format limitations, either the color texture (for
2434 // non-multisampling) or the color render buffer (for multisampling) will be
2435 // attached to the offscreen frame buffer. The render buffer has more
2436 // limited formats available to it, but the texture can't do multisampling.
2437 if (IsOffscreenBufferMultisampled()) {
[email protected]ed9f9cd2013-02-27 21:12:352438 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022439 offscreen_target_color_render_buffer_->Create();
2440 } else {
[email protected]ed9f9cd2013-02-27 21:12:352441 offscreen_target_color_texture_.reset(new BackTexture(this));
[email protected]34ff8b0c2010-10-01 20:06:022442 offscreen_target_color_texture_->Create();
2443 }
[email protected]ed9f9cd2013-02-27 21:12:352444 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]b9363b22010-06-09 22:06:152445 offscreen_target_depth_render_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:352446 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]b9363b22010-06-09 22:06:152447 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352448
2449 // Create the saved offscreen texture. The target frame buffer is copied
2450 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352451 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022452 offscreen_saved_frame_buffer_->Create();
2453 //
[email protected]ed9f9cd2013-02-27 21:12:352454 offscreen_saved_color_texture_.reset(new BackTexture(this));
[email protected]6217d392010-03-25 22:08:352455 offscreen_saved_color_texture_->Create();
2456
[email protected]6217d392010-03-25 22:08:352457 // Allocate the render buffers at their initial size and check the status
2458 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592459 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012460 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382461 Destroy(true);
[email protected]6217d392010-03-25 22:08:352462 return false;
2463 }
2464
[email protected]678a73f2012-12-19 19:22:092465 // Allocate the offscreen saved color texture.
2466 DCHECK(offscreen_saved_color_format_);
2467 offscreen_saved_color_texture_->AllocateStorage(
2468 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2469
2470 offscreen_saved_frame_buffer_->AttachRenderTexture(
2471 offscreen_saved_color_texture_.get());
2472 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2473 GL_FRAMEBUFFER_COMPLETE) {
2474 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2475 Destroy(true);
2476 return false;
2477 }
2478
[email protected]6217d392010-03-25 22:08:352479 // Bind to the new default frame buffer (the offscreen target frame buffer).
2480 // This should now be associated with ID zero.
2481 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2482 }
2483
[email protected]295faf4b2012-01-25 23:31:412484 // Clear the backbuffer.
2485 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2486
[email protected]76a0ee102010-04-07 21:03:042487 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2488 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2489 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372490 // mailing list archives. It also implicitly enables the desktop GL
2491 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2492 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152493 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2494 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372495 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152496 }
[email protected]de17df392010-04-23 21:09:412497
[email protected]706b69f2012-07-27 04:59:302498 has_robustness_extension_ =
2499 context->HasExtension("GL_ARB_robustness") ||
2500 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432501
[email protected]c2f8c8402010-12-06 18:07:242502 if (!InitializeShaderTranslator()) {
2503 return false;
[email protected]de17df392010-04-23 21:09:412504 }
[email protected]76a0ee102010-04-07 21:03:042505
[email protected]e259eb412012-10-13 05:47:242506 state_.viewport_width = size.width();
2507 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282508
[email protected]5904806b2012-05-08 18:10:222509 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282510 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022511 viewport_max_width_ = viewport_params[0];
2512 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282513
[email protected]88a61bf2012-10-27 13:00:422514 state_.scissor_width = state_.viewport_width;
2515 state_.scissor_height = state_.viewport_height;
2516
[email protected]11f3e702012-06-19 19:00:012517 // Set all the default state because some GL drivers get it wrong.
[email protected]f731b9462012-10-30 00:35:222518 state_.InitCapabilities();
2519 state_.InitState();
[email protected]e259eb412012-10-13 05:47:242520 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]88a61bf2012-10-27 13:00:422521 glHint(GL_GENERATE_MIPMAP_HINT, state_.hint_generate_mipmap);
[email protected]e259eb412012-10-13 05:47:242522 glPixelStorei(GL_PACK_ALIGNMENT, state_.pack_alignment);
[email protected]e259eb412012-10-13 05:47:242523 glPixelStorei(GL_UNPACK_ALIGNMENT, state_.unpack_alignment);
[email protected]11f3e702012-06-19 19:00:012524
2525 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2526 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2527 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2528 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2529
[email protected]62e155e2012-10-23 22:43:152530 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462531 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2532 }
[email protected]dd289a5d62012-06-30 22:05:462533
[email protected]97419c02013-04-10 02:52:382534 // Only compositor contexts are known to use only the subset of GL
2535 // that can be safely migrated between the iGPU and the dGPU. Mark
2536 // those contexts as safe to forcibly transition between the GPUs.
2537 // http://crbug.com/180876, http://crbug.com/227228
2538 if (!offscreen)
2539 context_->SetSafeToForceGpuSwitch();
2540
[email protected]32145a92012-12-17 09:01:592541 // Create a delegate to perform async pixel transfers.
2542 async_pixel_transfer_delegate_ =
2543 gfx::AsyncPixelTransferDelegate::Create(context.get());
2544
[email protected]246a70452010-03-05 21:53:502545 return true;
[email protected]96449d2c2009-11-25 00:01:322546}
2547
[email protected]302ce6d2011-07-07 23:28:112548void GLES2DecoderImpl::UpdateCapabilities() {
2549 util_.set_num_compressed_texture_formats(
2550 validators_->compressed_texture_format.GetValues().size());
2551 util_.set_num_shader_binary_formats(
2552 validators_->shader_binary_format.GetValues().size());
2553}
2554
[email protected]c2f8c8402010-12-06 18:07:242555bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442556 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2557
[email protected]c2f8c8402010-12-06 18:07:242558 if (!use_shader_translator_) {
2559 return true;
2560 }
2561 ShBuiltInResources resources;
2562 ShInitBuiltInResources(&resources);
2563 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2564 resources.MaxVertexUniformVectors =
2565 group_->max_vertex_uniform_vectors();
2566 resources.MaxVaryingVectors = group_->max_varying_vectors();
2567 resources.MaxVertexTextureImageUnits =
2568 group_->max_vertex_texture_image_units();
2569 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2570 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2571 resources.MaxFragmentUniformVectors =
2572 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492573 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]f0d74742011-10-03 16:31:042574
[email protected]9e98f61b2013-03-05 02:21:142575#if (ANGLE_SH_VERSION >= 110)
[email protected]8dc1bf92013-03-12 03:58:212576 GLint range[2];
2577 GLint precision = 0;
2578 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2579 range, &precision);
2580 resources.FragmentPrecisionHigh = ((range[0] >= 62) &&
2581 (range[1] >= 62) &&
2582 (precision >= 16));
[email protected]9e98f61b2013-03-05 02:21:142583#endif
2584
[email protected]f0d74742011-10-03 16:31:042585 if (force_webgl_glsl_validation_) {
2586 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
2587 } else {
2588 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152589 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462590 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152591 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062592 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152593 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492594 resources.EXT_draw_buffers =
2595 features().ext_draw_buffers ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042596 }
2597
[email protected]26b61442013-03-17 16:12:012598 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2599 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052600 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022601#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]6aedcdc2013-01-24 01:25:052602 resources.HashFunction = &CityHashForAngle;
[email protected]3d944a82013-02-12 19:09:022603#else
2604 resources.HashFunction = &CityHash64;
2605#endif
[email protected]6aedcdc2013-01-24 01:25:052606 else
2607 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122608 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2609 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2610 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
2611 ShaderTranslatorInterface::GlslBuiltInFunctionBehavior function_behavior =
[email protected]62e155e2012-10-23 22:43:152612 workarounds().needs_glsl_built_in_function_emulation ?
[email protected]a2a0fe762011-09-20 00:59:122613 ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated :
2614 ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal;
[email protected]87fb6ab2012-06-13 22:28:042615
2616 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance();
2617 vertex_translator_ = cache->GetTranslator(
2618 SH_VERTEX_SHADER, shader_spec, &resources,
2619 implementation_type, function_behavior);
2620 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242621 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382622 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242623 return false;
2624 }
[email protected]87fb6ab2012-06-13 22:28:042625
2626 fragment_translator_ = cache->GetTranslator(
2627 SH_FRAGMENT_SHADER, shader_spec, &resources,
2628 implementation_type, function_behavior);
2629 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242630 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382631 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242632 return false;
2633 }
2634 return true;
2635}
2636
[email protected]ae51d192010-04-27 00:48:032637bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472638 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352639 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032640 return false;
2641 }
2642 }
[email protected]40d90a22013-04-09 03:39:552643 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032644 glGenBuffersARB(n, service_ids.get());
2645 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352646 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032647 }
2648 return true;
2649}
2650
2651bool GLES2DecoderImpl::GenFramebuffersHelper(
2652 GLsizei n, const GLuint* client_ids) {
2653 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352654 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032655 return false;
2656 }
2657 }
[email protected]40d90a22013-04-09 03:39:552658 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032659 glGenFramebuffersEXT(n, service_ids.get());
2660 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352661 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032662 }
2663 return true;
2664}
2665
2666bool GLES2DecoderImpl::GenRenderbuffersHelper(
2667 GLsizei n, const GLuint* client_ids) {
2668 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352669 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032670 return false;
2671 }
2672 }
[email protected]40d90a22013-04-09 03:39:552673 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032674 glGenRenderbuffersEXT(n, service_ids.get());
2675 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352676 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032677 }
2678 return true;
2679}
2680
2681bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2682 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352683 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032684 return false;
2685 }
2686 }
[email protected]40d90a22013-04-09 03:39:552687 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032688 glGenTextures(n, service_ids.get());
2689 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352690 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032691 }
2692 return true;
2693}
2694
2695void GLES2DecoderImpl::DeleteBuffersHelper(
2696 GLsizei n, const GLuint* client_ids) {
2697 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212698 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102699 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242700 state_.vertex_attrib_manager->Unbind(buffer);
2701 if (state_.bound_array_buffer == buffer) {
2702 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102703 }
[email protected]ed9f9cd2013-02-27 21:12:352704 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032705 }
[email protected]a93bb842010-02-16 23:03:472706 }
[email protected]07f54fcc2009-12-22 02:46:302707}
2708
[email protected]ae51d192010-04-27 00:48:032709void GLES2DecoderImpl::DeleteFramebuffersHelper(
2710 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452711 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152712 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112713
[email protected]a25fa872010-03-25 02:57:582714 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352715 Framebuffer* framebuffer =
2716 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102717 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242718 if (framebuffer == state_.bound_draw_framebuffer) {
2719 state_.bound_draw_framebuffer = NULL;
[email protected]88a61bf2012-10-27 13:00:422720 clear_state_dirty_ = true;
[email protected]ebfb73c2012-08-15 02:37:452721 GLenum target = supports_separate_framebuffer_binds ?
2722 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112723 glBindFramebufferEXT(target, GetBackbufferServiceId());
2724 }
[email protected]e259eb412012-10-13 05:47:242725 if (framebuffer == state_.bound_read_framebuffer) {
2726 state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452727 GLenum target = supports_separate_framebuffer_binds ?
2728 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112729 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462730 }
[email protected]70d34263c2013-01-09 00:27:452731 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352732 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032733 }
[email protected]a25fa872010-03-25 02:57:582734 }
[email protected]07f54fcc2009-12-22 02:46:302735}
2736
[email protected]ae51d192010-04-27 00:48:032737void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2738 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452739 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152740 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582741 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352742 Renderbuffer* renderbuffer =
2743 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102744 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242745 if (state_.bound_renderbuffer == renderbuffer) {
2746 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102747 }
2748 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452749 if (supports_separate_framebuffer_binds) {
[email protected]e259eb412012-10-13 05:47:242750 if (state_.bound_read_framebuffer) {
2751 state_.bound_read_framebuffer->UnbindRenderbuffer(
[email protected]ebfb73c2012-08-15 02:37:452752 GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102753 }
[email protected]e259eb412012-10-13 05:47:242754 if (state_.bound_draw_framebuffer) {
2755 state_.bound_draw_framebuffer->UnbindRenderbuffer(
[email protected]ebfb73c2012-08-15 02:37:452756 GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102757 }
2758 } else {
[email protected]e259eb412012-10-13 05:47:242759 if (state_.bound_draw_framebuffer) {
2760 state_.bound_draw_framebuffer->UnbindRenderbuffer(
[email protected]a0b78dc2011-11-11 10:43:102761 GL_FRAMEBUFFER, renderbuffer);
2762 }
2763 }
[email protected]88a61bf2012-10-27 13:00:422764 clear_state_dirty_ = true;
[email protected]ed9f9cd2013-02-27 21:12:352765 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032766 }
[email protected]a25fa872010-03-25 02:57:582767 }
[email protected]07f54fcc2009-12-22 02:46:302768}
2769
[email protected]ae51d192010-04-27 00:48:032770void GLES2DecoderImpl::DeleteTexturesHelper(
2771 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452772 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152773 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472774 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352775 Texture* texture = GetTexture(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102776 if (texture && !texture->IsDeleted()) {
2777 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:422778 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462779 }
[email protected]a0b78dc2011-11-11 10:43:102780 // Unbind texture from texture units.
[email protected]1868a342012-11-07 15:56:022781 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]e259eb412012-10-13 05:47:242782 state_.texture_units[jj].Unbind(texture);
[email protected]a0b78dc2011-11-11 10:43:102783 }
2784 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452785 if (supports_separate_framebuffer_binds) {
[email protected]e259eb412012-10-13 05:47:242786 if (state_.bound_read_framebuffer) {
2787 state_.bound_read_framebuffer->UnbindTexture(
[email protected]ebfb73c2012-08-15 02:37:452788 GL_READ_FRAMEBUFFER_EXT, texture);
[email protected]a0b78dc2011-11-11 10:43:102789 }
[email protected]e259eb412012-10-13 05:47:242790 if (state_.bound_draw_framebuffer) {
2791 state_.bound_draw_framebuffer->UnbindTexture(
[email protected]ebfb73c2012-08-15 02:37:452792 GL_DRAW_FRAMEBUFFER_EXT, texture);
[email protected]a0b78dc2011-11-11 10:43:102793 }
2794 } else {
[email protected]e259eb412012-10-13 05:47:242795 if (state_.bound_draw_framebuffer) {
2796 state_.bound_draw_framebuffer->UnbindTexture(GL_FRAMEBUFFER, texture);
[email protected]a0b78dc2011-11-11 10:43:102797 }
2798 }
2799 GLuint service_id = texture->service_id();
2800 if (texture->IsStreamTexture() && stream_texture_manager_) {
[email protected]b0af4f52011-09-28 22:04:422801 stream_texture_manager_->DestroyStreamTexture(service_id);
2802 }
[email protected]e51bdf32011-11-23 22:21:462803#if defined(OS_MACOSX)
2804 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
2805 ReleaseIOSurfaceForTexture(service_id);
2806 }
2807#endif
[email protected]ed9f9cd2013-02-27 21:12:352808 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032809 }
[email protected]a93bb842010-02-16 23:03:472810 }
[email protected]07f54fcc2009-12-22 02:46:302811}
2812
[email protected]43f28f832010-02-03 02:28:482813// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:322814
[email protected]eb54a562010-01-20 21:55:182815bool GLES2DecoderImpl::MakeCurrent() {
[email protected]63c9b052012-05-17 18:27:382816 if (!context_.get() || !context_->MakeCurrent(surface_.get()))
2817 return false;
2818
2819 if (WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:432820 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:292821
2822 // Some D3D drivers cannot recover from device lost in the GPU process
2823 // sandbox. Allow a new GPU process to launch.
2824 if (workarounds().exit_on_context_lost) {
2825 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
2826 << " a D3D device in the Chrome GPU process sandbox.";
2827 exit(0);
2828 }
2829
[email protected]63c9b052012-05-17 18:27:382830 return false;
[email protected]38d139d2011-07-14 00:38:432831 }
2832
[email protected]69a8701e2013-03-07 21:31:092833 ProcessFinishedAsyncTransfers();
2834 if (workarounds().flush_on_context_switch)
2835 glFlush();
2836
2837 return true;
2838}
2839
2840void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]fe8d73c2013-02-16 22:37:322841 if (engine() && query_manager_.get())
2842 query_manager_->ProcessPendingTransferQueries();
2843
[email protected]5b3a8e02013-03-13 05:36:442844 // TODO(epenner): Is there a better place to do this?
2845 // This needs to occur before we execute any batch of commands
2846 // from the client, as the client may have recieved an async
2847 // completion while issuing those commands.
2848 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]2b1767cf2013-03-16 09:25:052849 // TODO(reveman): We should avoid using a bool return value to determine
2850 // if we need to restore some state. crbug.com/196303
[email protected]5b3a8e02013-03-13 05:36:442851 if (async_pixel_transfer_delegate_->BindCompletedAsyncTransfers())
[email protected]32145a92012-12-17 09:01:592852 RestoreCurrentTexture2DBindings();
[email protected]eb54a562010-01-20 21:55:182853}
2854
[email protected]a96a6022011-11-04 00:58:122855void GLES2DecoderImpl::ReleaseCurrent() {
2856 if (context_.get())
2857 context_->ReleaseCurrent(surface_.get());
2858}
2859
[email protected]8e3e0662010-08-23 18:46:302860void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() {
[email protected]ed9f9cd2013-02-27 21:12:352861 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:202862 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
[email protected]8e3e0662010-08-23 18:46:302863 glBindRenderbufferEXT(
[email protected]0d6bfdc2011-11-02 01:32:202864 GL_RENDERBUFFER, renderbuffer ? renderbuffer->service_id() : 0);
[email protected]8e3e0662010-08-23 18:46:302865}
2866
2867static void RebindCurrentFramebuffer(
2868 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:062869 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:242870 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:062871 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:462872
[email protected]a3783712012-01-20 22:18:242873 if (framebuffer_id == 0) {
2874 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:302875 }
[email protected]297ca1c2011-06-20 23:08:462876
[email protected]8e3e0662010-08-23 18:46:302877 glBindFramebufferEXT(target, framebuffer_id);
2878}
2879
2880void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]88a61bf2012-10-27 13:00:422881 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462882
[email protected]62e155e2012-10-23 22:43:152883 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:302884 RebindCurrentFramebuffer(
2885 GL_FRAMEBUFFER,
[email protected]e259eb412012-10-13 05:47:242886 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242887 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302888 } else {
2889 RebindCurrentFramebuffer(
2890 GL_READ_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242891 state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242892 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302893 RebindCurrentFramebuffer(
2894 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242895 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242896 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302897 }
[email protected]70d34263c2013-01-09 00:27:452898 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:302899}
2900
2901void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() {
[email protected]e259eb412012-10-13 05:47:242902 TextureUnit& info = state_.texture_units[0];
[email protected]8e3e0662010-08-23 18:46:302903 GLuint last_id;
2904 if (info.bound_texture_2d) {
2905 last_id = info.bound_texture_2d->service_id();
2906 } else {
2907 last_id = 0;
2908 }
2909
2910 glBindTexture(GL_TEXTURE_2D, last_id);
[email protected]e259eb412012-10-13 05:47:242911 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]8e3e0662010-08-23 18:46:302912}
2913
[email protected]0d6bfdc2011-11-02 01:32:202914bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:352915 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:202916 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:102917 if (!framebuffer) {
[email protected]60f22d32012-12-12 00:31:582918 if (backbuffer_needs_clear_bits_) {
2919 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
2920 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
2921 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2922 glClearStencil(0);
2923 glStencilMask(-1);
2924 glClearDepth(1.0f);
2925 glDepthMask(true);
2926 glDisable(GL_SCISSOR_TEST);
2927 glClear(backbuffer_needs_clear_bits_);
2928 backbuffer_needs_clear_bits_ = 0;
2929 RestoreClearState();
2930 }
[email protected]0d6bfdc2011-11-02 01:32:202931 return true;
2932 }
2933
[email protected]968351b2011-12-20 08:26:512934 if (framebuffer_manager()->IsComplete(framebuffer)) {
2935 return true;
2936 }
2937
[email protected]0d6bfdc2011-11-02 01:32:202938 GLenum completeness = framebuffer->IsPossiblyComplete();
2939 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512940 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432941 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:272942 return false;
2943 }
[email protected]0d6bfdc2011-11-02 01:32:202944
2945 // Are all the attachments cleared?
2946 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
2947 texture_manager()->HaveUnclearedMips()) {
2948 if (!framebuffer->IsCleared()) {
2949 // Can we clear them?
[email protected]73276522012-11-09 05:50:202950 if (framebuffer->GetStatus(texture_manager(), target) !=
2951 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512952 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432953 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2954 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:202955 return false;
2956 }
2957 ClearUnclearedAttachments(target, framebuffer);
2958 }
2959 }
2960
[email protected]968351b2011-12-20 08:26:512961 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:202962 if (framebuffer->GetStatus(texture_manager(), target) !=
2963 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512964 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432965 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2966 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:512967 return false;
2968 }
2969 framebuffer_manager()->MarkAsComplete(framebuffer);
2970 }
2971
[email protected]0d6bfdc2011-11-02 01:32:202972 // NOTE: At this point we don't know if the framebuffer is complete but
2973 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:272974 return true;
2975}
2976
[email protected]0d6bfdc2011-11-02 01:32:202977bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:152978 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:512979 bool valid = CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242980 state_.bound_draw_framebuffer, GL_FRAMEBUFFER_EXT, func_name);
[email protected]28718a92013-04-04 12:12:512981
2982 if (valid)
2983 OnUseFramebuffer();
2984
2985 return valid;
[email protected]0d6bfdc2011-11-02 01:32:202986 }
2987 return CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242988 state_.bound_draw_framebuffer,
2989 GL_DRAW_FRAMEBUFFER_EXT, func_name) &&
[email protected]0d6bfdc2011-11-02 01:32:202990 CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242991 state_.bound_read_framebuffer,
2992 GL_READ_FRAMEBUFFER_EXT, func_name);
[email protected]0d6bfdc2011-11-02 01:32:202993}
2994
[email protected]8e3e0662010-08-23 18:46:302995gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:352996 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452997 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202998 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:352999 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203000 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263001 if (attachment) {
3002 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503003 }
[email protected]9edc6b22010-12-23 02:00:263004 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023005 } else if (offscreen_target_frame_buffer_.get()) {
3006 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353007 } else {
[email protected]f62a5ab2011-05-23 20:34:153008 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023009 }
[email protected]246a70452010-03-05 21:53:503010}
3011
[email protected]9edc6b22010-12-23 02:00:263012GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353013 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453014 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203015 if (framebuffer != NULL) {
3016 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463017 } else if (offscreen_target_frame_buffer_.get()) {
3018 return offscreen_target_color_format_;
3019 } else {
3020 return back_buffer_color_format_;
3021 }
3022}
3023
3024GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353025 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453026 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203027 if (framebuffer != NULL) {
3028 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263029 } else if (offscreen_target_frame_buffer_.get()) {
3030 return offscreen_target_color_format_;
3031 } else {
[email protected]32fe9aa2011-01-21 23:47:133032 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263033 }
3034}
3035
[email protected]9a5afa432011-07-22 18:16:393036void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]34ff8b0c2010-10-01 20:06:023037 if (parent_) {
[email protected]2f2d7042010-04-14 21:45:583038 // Update the info about the offscreen saved color texture in the parent.
3039 // The reference to the parent is a weak pointer and will become null if the
3040 // parent is later destroyed.
[email protected]262d7aa2010-12-03 22:07:293041 TextureManager* parent_texture_manager = parent_->texture_manager();
[email protected]262d7aa2010-12-03 22:07:293042 parent_texture_manager->SetLevelInfo(
[email protected]8a61d872012-01-20 12:43:563043 offscreen_saved_color_texture_info_,
[email protected]ef526492010-06-02 23:12:253044 GL_TEXTURE_2D,
3045 0, // level
3046 GL_RGBA,
[email protected]799b4b22011-08-22 17:09:593047 offscreen_size_.width(),
3048 offscreen_size_.height(),
[email protected]ef526492010-06-02 23:12:253049 1, // depth
3050 0, // border
3051 GL_RGBA,
[email protected]0d6bfdc2011-11-02 01:32:203052 GL_UNSIGNED_BYTE,
3053 true);
[email protected]262d7aa2010-12-03 22:07:293054 parent_texture_manager->SetParameter(
[email protected]02965c22013-03-09 02:40:073055 "UpdateParentTextureInfo",
[email protected]d3eba342013-04-18 21:11:503056 GetErrorState(),
[email protected]8a61d872012-01-20 12:43:563057 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:043058 GL_TEXTURE_MAG_FILTER,
3059 GL_NEAREST);
[email protected]262d7aa2010-12-03 22:07:293060 parent_texture_manager->SetParameter(
[email protected]02965c22013-03-09 02:40:073061 "UpdateParentTextureInfo",
[email protected]d3eba342013-04-18 21:11:503062 GetErrorState(),
[email protected]8a61d872012-01-20 12:43:563063 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:043064 GL_TEXTURE_MIN_FILTER,
3065 GL_NEAREST);
[email protected]262d7aa2010-12-03 22:07:293066 parent_texture_manager->SetParameter(
[email protected]02965c22013-03-09 02:40:073067 "UpdateParentTextureInfo",
[email protected]d3eba342013-04-18 21:11:503068 GetErrorState(),
[email protected]8a61d872012-01-20 12:43:563069 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:043070 GL_TEXTURE_WRAP_S,
3071 GL_CLAMP_TO_EDGE);
[email protected]262d7aa2010-12-03 22:07:293072 parent_texture_manager->SetParameter(
[email protected]02965c22013-03-09 02:40:073073 "UpdateParentTextureInfo",
[email protected]d3eba342013-04-18 21:11:503074 GetErrorState(),
[email protected]8a61d872012-01-20 12:43:563075 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:043076 GL_TEXTURE_WRAP_T,
3077 GL_CLAMP_TO_EDGE);
[email protected]8a61d872012-01-20 12:43:563078 } else {
3079 offscreen_saved_color_texture_info_ = NULL;
[email protected]0c8c9d22010-06-25 17:36:393080 }
[email protected]6217d392010-03-25 22:08:353081}
3082
[email protected]799b4b22011-08-22 17:09:593083void GLES2DecoderImpl::SetResizeCallback(
[email protected]9d37f062011-11-22 01:24:523084 const base::Callback<void(gfx::Size)>& callback) {
3085 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003086}
3087
[email protected]1d82e822013-04-10 21:32:323088Logger* GLES2DecoderImpl::GetLogger() {
3089 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523090}
3091
[email protected]d3eba342013-04-18 21:11:503092ErrorState* GLES2DecoderImpl::GetErrorState() {
3093 return state_.GetErrorState();
3094}
3095
[email protected]e3932abb2013-03-13 00:01:373096void GLES2DecoderImpl::SetShaderCacheCallback(
3097 const ShaderCacheCallback& callback) {
3098 shader_cache_callback_ = callback;
3099}
3100
[email protected]840a7e462013-02-27 01:29:513101void GLES2DecoderImpl::SetWaitSyncPointCallback(
3102 const WaitSyncPointCallback& callback) {
3103 wait_sync_point_callback_ = callback;
3104}
3105
[email protected]b0af4f52011-09-28 22:04:423106void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) {
3107 stream_texture_manager_ = manager;
3108}
3109
[email protected]32145a92012-12-17 09:01:593110gfx::AsyncPixelTransferDelegate*
3111 GLES2DecoderImpl::GetAsyncPixelTransferDelegate() {
3112 return async_pixel_transfer_delegate_.get();
3113}
3114
3115void GLES2DecoderImpl::SetAsyncPixelTransferDelegate(
3116 gfx::AsyncPixelTransferDelegate* delegate) {
3117 async_pixel_transfer_delegate_ = make_scoped_ptr(delegate);
3118}
3119
[email protected]1318e922010-09-17 22:03:163120bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3121 uint32* service_texture_id) {
[email protected]02965c22013-03-09 02:40:073122 Texture* texture = texture_manager()->GetTexture(client_texture_id);
[email protected]1318e922010-09-17 22:03:163123 if (texture) {
3124 *service_texture_id = texture->service_id();
3125 return true;
3126 }
3127 return false;
3128}
3129
[email protected]63b465922012-09-06 02:04:523130uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]b9804322013-01-08 17:54:123131 return texture_upload_count_ +
3132 async_pixel_transfer_delegate_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523133}
3134
3135base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]b9804322013-01-08 17:54:123136 return total_texture_upload_time_ +
3137 async_pixel_transfer_delegate_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523138}
3139
3140base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3141 return total_processing_commands_time_;
3142}
3143
[email protected]dc25dda2012-09-27 21:36:303144void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3145 total_processing_commands_time_ += time;
3146}
3147
[email protected]63c9b052012-05-17 18:27:383148void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063149 if (!initialized())
3150 return;
3151
[email protected]63c9b052012-05-17 18:27:383152 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053153
[email protected]c826d732012-02-09 04:40:263154 ChildList children = children_;
3155 for (ChildList::iterator it = children.begin(); it != children.end(); ++it)
3156 (*it)->SetParent(NULL, 0);
3157 DCHECK(children_.empty());
[email protected]3c644d82011-06-20 19:58:243158 SetParent(NULL, 0);
3159
[email protected]80eb6b52012-01-19 00:14:413160 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243161 state_.vertex_attrib_manager = NULL;
[email protected]944b62f32012-09-27 02:20:463162 default_vertex_attrib_manager_ = NULL;
[email protected]1868a342012-11-07 15:56:023163 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243164 state_.bound_array_buffer = NULL;
3165 state_.current_query = NULL;
3166 state_.current_program = NULL;
3167 state_.bound_read_framebuffer = NULL;
3168 state_.bound_draw_framebuffer = NULL;
3169 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413170
[email protected]eadc96792010-10-27 19:39:393171 if (have_context) {
[email protected]c322e882012-05-23 18:06:183172 if (copy_texture_CHROMIUM_.get()) {
3173 copy_texture_CHROMIUM_->Destroy();
3174 copy_texture_CHROMIUM_.reset();
3175 }
[email protected]43410e92012-04-20 17:06:283176
[email protected]e259eb412012-10-13 05:47:243177 if (state_.current_program) {
3178 program_manager()->UnuseProgram(shader_manager(), state_.current_program);
3179 state_.current_program = NULL;
[email protected]ca488e12010-12-13 20:06:143180 }
3181
[email protected]b1122982010-05-17 23:04:243182 if (attrib_0_buffer_id_) {
3183 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3184 }
[email protected]8fbedc02010-11-18 18:43:403185 if (fixed_attrib_buffer_id_) {
3186 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3187 }
[email protected]b1122982010-05-17 23:04:243188
[email protected]97872062010-11-03 19:07:053189 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543190 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053191 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543192 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053193 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023194 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053195 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153196 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053197 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153198 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053199 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023200 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053201 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543202 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273203 if (offscreen_resolved_frame_buffer_.get())
3204 offscreen_resolved_frame_buffer_->Destroy();
3205 if (offscreen_resolved_color_texture_.get())
3206 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053207 } else {
3208 if (offscreen_target_frame_buffer_.get())
3209 offscreen_target_frame_buffer_->Invalidate();
3210 if (offscreen_target_color_texture_.get())
3211 offscreen_target_color_texture_->Invalidate();
3212 if (offscreen_target_color_render_buffer_.get())
3213 offscreen_target_color_render_buffer_->Invalidate();
3214 if (offscreen_target_depth_render_buffer_.get())
3215 offscreen_target_depth_render_buffer_->Invalidate();
3216 if (offscreen_target_stencil_render_buffer_.get())
3217 offscreen_target_stencil_render_buffer_->Invalidate();
3218 if (offscreen_saved_frame_buffer_.get())
3219 offscreen_saved_frame_buffer_->Invalidate();
3220 if (offscreen_saved_color_texture_.get())
3221 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273222 if (offscreen_resolved_frame_buffer_.get())
3223 offscreen_resolved_frame_buffer_->Invalidate();
3224 if (offscreen_resolved_color_texture_.get())
3225 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023226 }
[email protected]43410e92012-04-20 17:06:283227 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053228
[email protected]882ba1e22012-03-08 19:02:533229 if (query_manager_.get()) {
3230 query_manager_->Destroy(have_context);
3231 query_manager_.reset();
3232 }
3233
[email protected]944b62f32012-09-27 02:20:463234 if (vertex_array_manager_ .get()) {
3235 vertex_array_manager_->Destroy(have_context);
3236 vertex_array_manager_.reset();
3237 }
3238
[email protected]97872062010-11-03 19:07:053239 offscreen_target_frame_buffer_.reset();
3240 offscreen_target_color_texture_.reset();
3241 offscreen_target_color_render_buffer_.reset();
3242 offscreen_target_depth_render_buffer_.reset();
3243 offscreen_target_stencil_render_buffer_.reset();
3244 offscreen_saved_frame_buffer_.reset();
3245 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273246 offscreen_resolved_frame_buffer_.reset();
3247 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463248
[email protected]2d9d3b92013-01-18 01:07:233249 if (group_) {
3250 group_->Destroy(this, have_context);
3251 group_ = NULL;
3252 }
3253
3254 if (context_.get()) {
3255 context_->ReleaseCurrent(NULL);
3256 context_ = NULL;
3257 }
3258
[email protected]e51bdf32011-11-23 22:21:463259#if defined(OS_MACOSX)
3260 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3261 it != texture_to_io_surface_map_.end(); ++it) {
3262 CFRelease(it->second);
3263 }
3264 texture_to_io_surface_map_.clear();
3265#endif
[email protected]96449d2c2009-11-25 00:01:323266}
3267
[email protected]63c9b052012-05-17 18:27:383268void GLES2DecoderImpl::SetSurface(
3269 const scoped_refptr<gfx::GLSurface>& surface) {
3270 DCHECK(context_->IsCurrent(NULL));
3271 DCHECK(surface_.get());
3272 surface_ = surface;
3273 RestoreCurrentFramebufferBindings();
3274}
3275
[email protected]3c644d82011-06-20 19:58:243276bool GLES2DecoderImpl::SetParent(GLES2Decoder* new_parent,
3277 uint32 new_parent_texture_id) {
[email protected]9a5afa432011-07-22 18:16:393278 if (!offscreen_saved_color_texture_.get())
3279 return false;
3280
[email protected]3c644d82011-06-20 19:58:243281 // Remove the saved frame buffer mapping from the parent decoder. The
3282 // parent pointer is a weak pointer so it will be null if the parent has
3283 // already been destroyed.
3284 if (parent_) {
[email protected]c826d732012-02-09 04:40:263285 ChildList::iterator it = std::find(
3286 parent_->children_.begin(),
3287 parent_->children_.end(),
3288 this);
3289 DCHECK(it != parent_->children_.end());
3290 parent_->children_.erase(it);
[email protected]3c644d82011-06-20 19:58:243291 // First check the texture has been mapped into the parent. This might not
3292 // be the case if initialization failed midway through.
3293 GLuint service_id = offscreen_saved_color_texture_->id();
3294 GLuint client_id = 0;
3295 if (parent_->texture_manager()->GetClientId(service_id, &client_id)) {
[email protected]ed9f9cd2013-02-27 21:12:353296 parent_->texture_manager()->RemoveTexture(client_id);
[email protected]3c644d82011-06-20 19:58:243297 }
3298 }
3299
3300 GLES2DecoderImpl* new_parent_impl = static_cast<GLES2DecoderImpl*>(
3301 new_parent);
3302 if (new_parent_impl) {
[email protected]c826d732012-02-09 04:40:263303#ifndef NDEBUG
3304 ChildList::iterator it = std::find(
3305 new_parent_impl->children_.begin(),
3306 new_parent_impl->children_.end(),
3307 this);
3308 DCHECK(it == new_parent_impl->children_.end());
3309#endif
3310 new_parent_impl->children_.push_back(this);
[email protected]3c644d82011-06-20 19:58:243311 // Map the ID of the saved offscreen texture into the parent so that
3312 // it can reference it.
3313 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]98687862011-07-11 23:31:303314
3315 // Replace texture info when ID is already in use by parent.
[email protected]ed9f9cd2013-02-27 21:12:353316 if (new_parent_impl->texture_manager()->GetTexture(
[email protected]80eb6b52012-01-19 00:14:413317 new_parent_texture_id))
[email protected]ed9f9cd2013-02-27 21:12:353318 new_parent_impl->texture_manager()->RemoveTexture(
[email protected]80eb6b52012-01-19 00:14:413319 new_parent_texture_id);
[email protected]98687862011-07-11 23:31:303320
[email protected]8a61d872012-01-20 12:43:563321 offscreen_saved_color_texture_info_ =
[email protected]ed9f9cd2013-02-27 21:12:353322 new_parent_impl->CreateTexture(new_parent_texture_id, service_id);
[email protected]8a61d872012-01-20 12:43:563323 offscreen_saved_color_texture_info_->SetNotOwned();
3324 new_parent_impl->texture_manager()->
[email protected]02965c22013-03-09 02:40:073325 SetTarget(offscreen_saved_color_texture_info_, GL_TEXTURE_2D);
[email protected]3c644d82011-06-20 19:58:243326
[email protected]ee1e6aa2012-11-29 09:24:103327 parent_ = base::AsWeakPtr<GLES2DecoderImpl>(new_parent_impl);
[email protected]9a5afa432011-07-22 18:16:393328
3329 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243330 } else {
3331 parent_.reset();
[email protected]8a61d872012-01-20 12:43:563332 offscreen_saved_color_texture_info_ = NULL;
[email protected]3c644d82011-06-20 19:58:243333 }
3334
3335 return true;
3336}
3337
[email protected]260ddc4e2012-06-28 00:01:533338size_t GLES2DecoderImpl::GetBackbufferMemoryTotal() {
[email protected]1078f912011-12-23 13:12:143339 size_t total = 0;
3340 if (offscreen_target_frame_buffer_.get()) {
3341 if (offscreen_target_color_texture_.get()) {
3342 total += offscreen_target_color_texture_->estimated_size();
3343 }
3344 if (offscreen_target_color_render_buffer_.get()) {
3345 total += offscreen_target_color_render_buffer_->estimated_size();
3346 }
3347 if (offscreen_target_depth_render_buffer_.get()) {
3348 total += offscreen_target_depth_render_buffer_->estimated_size();
3349 }
3350 if (offscreen_target_stencil_render_buffer_.get()) {
3351 total += offscreen_target_stencil_render_buffer_->estimated_size();
3352 }
3353 if (offscreen_saved_color_texture_.get()) {
3354 total += offscreen_saved_color_texture_->estimated_size();
3355 }
3356 if (offscreen_resolved_color_texture_.get()) {
3357 total += offscreen_resolved_color_texture_->estimated_size();
3358 }
3359 } else {
3360 gfx::Size size = surface_->GetSize();
3361 total += size.width() * size.height() *
3362 GLES2Util::RenderbufferBytesPerPixel(back_buffer_color_format_);
3363 }
[email protected]260ddc4e2012-06-28 00:01:533364 return total;
[email protected]1078f912011-12-23 13:12:143365}
3366
[email protected]799b4b22011-08-22 17:09:593367bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3368 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3369 if (!is_offscreen) {
3370 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3371 << " with an onscreen framebuffer.";
3372 return false;
3373 }
3374
3375 if (offscreen_size_ == size)
3376 return true;
3377
3378 offscreen_size_ = size;
3379 int w = offscreen_size_.width();
3380 int h = offscreen_size_.height();
3381 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3382 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3383 << "to allocate storage due to excessive dimensions.";
3384 return false;
3385 }
3386
3387 // Reallocate the offscreen target buffers.
3388 DCHECK(offscreen_target_color_format_);
3389 if (IsOffscreenBufferMultisampled()) {
3390 if (!offscreen_target_color_render_buffer_->AllocateStorage(
3391 offscreen_size_, offscreen_target_color_format_,
3392 offscreen_target_samples_)) {
3393 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3394 << "to allocate storage for offscreen target color buffer.";
3395 return false;
3396 }
3397 } else {
3398 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093399 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593400 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3401 << "to allocate storage for offscreen target color texture.";
3402 return false;
3403 }
3404 }
3405 if (offscreen_target_depth_format_ &&
3406 !offscreen_target_depth_render_buffer_->AllocateStorage(
3407 offscreen_size_, offscreen_target_depth_format_,
3408 offscreen_target_samples_)) {
3409 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3410 << "to allocate storage for offscreen target depth buffer.";
3411 return false;
3412 }
3413 if (offscreen_target_stencil_format_ &&
3414 !offscreen_target_stencil_render_buffer_->AllocateStorage(
3415 offscreen_size_, offscreen_target_stencil_format_,
3416 offscreen_target_samples_)) {
3417 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3418 << "to allocate storage for offscreen target stencil buffer.";
3419 return false;
3420 }
3421
3422 // Attach the offscreen target buffers to the target frame buffer.
3423 if (IsOffscreenBufferMultisampled()) {
3424 offscreen_target_frame_buffer_->AttachRenderBuffer(
3425 GL_COLOR_ATTACHMENT0,
3426 offscreen_target_color_render_buffer_.get());
3427 } else {
3428 offscreen_target_frame_buffer_->AttachRenderTexture(
3429 offscreen_target_color_texture_.get());
3430 }
3431 if (offscreen_target_depth_format_) {
3432 offscreen_target_frame_buffer_->AttachRenderBuffer(
3433 GL_DEPTH_ATTACHMENT,
3434 offscreen_target_depth_render_buffer_.get());
3435 }
3436 const bool packed_depth_stencil =
3437 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3438 if (packed_depth_stencil) {
3439 offscreen_target_frame_buffer_->AttachRenderBuffer(
3440 GL_STENCIL_ATTACHMENT,
3441 offscreen_target_depth_render_buffer_.get());
3442 } else if (offscreen_target_stencil_format_) {
3443 offscreen_target_frame_buffer_->AttachRenderBuffer(
3444 GL_STENCIL_ATTACHMENT,
3445 offscreen_target_stencil_render_buffer_.get());
3446 }
3447
3448 if (offscreen_target_frame_buffer_->CheckStatus() !=
3449 GL_FRAMEBUFFER_COMPLETE) {
3450 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3451 << "because offscreen FBO was incomplete.";
3452 return false;
3453 }
3454
3455 // Clear the target frame buffer.
3456 {
3457 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3458 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3459 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3460 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3461 glClearStencil(0);
3462 glStencilMaskSeparate(GL_FRONT, -1);
3463 glStencilMaskSeparate(GL_BACK, -1);
3464 glClearDepth(0);
3465 glDepthMask(GL_TRUE);
3466 glDisable(GL_SCISSOR_TEST);
3467 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3468 RestoreClearState();
3469 }
[email protected]d85ef76d2011-09-08 22:21:433470
3471 // Destroy the offscreen resolved framebuffers.
3472 if (offscreen_resolved_frame_buffer_.get())
3473 offscreen_resolved_frame_buffer_->Destroy();
3474 if (offscreen_resolved_color_texture_.get())
3475 offscreen_resolved_color_texture_->Destroy();
3476 offscreen_resolved_color_texture_.reset();
3477 offscreen_resolved_frame_buffer_.reset();
3478
[email protected]799b4b22011-08-22 17:09:593479 return true;
[email protected]6217d392010-03-25 22:08:353480}
3481
[email protected]799b4b22011-08-22 17:09:593482error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:353483 uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) {
[email protected]09e17272012-11-30 10:30:443484 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023485 return error::kDeferCommandUntilLater;
3486
[email protected]799b4b22011-08-22 17:09:593487 GLuint width = static_cast<GLuint>(c.width);
3488 GLuint height = static_cast<GLuint>(c.height);
3489 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413490
3491 width = std::max(1U, width);
3492 height = std::max(1U, height);
3493
[email protected]a0d989162011-11-22 13:15:073494#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3495 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003496 // Make sure that we are done drawing to the back buffer before resizing.
3497 glFinish();
3498#endif
[email protected]799b4b22011-08-22 17:09:593499 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3500 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493501 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3502 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3503 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593504 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493505 }
[email protected]7ff86b92010-11-25 17:50:003506 }
[email protected]799b4b22011-08-22 17:09:593507
[email protected]9d37f062011-11-22 01:24:523508 if (!resize_callback_.is_null()) {
3509 resize_callback_.Run(gfx::Size(width, height));
[email protected]0e9346b2013-03-16 16:35:443510 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493511 if (!context_->IsCurrent(surface_.get())) {
3512 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3513 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053514 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493515 }
[email protected]658f7562011-09-09 05:24:053516 }
[email protected]799b4b22011-08-22 17:09:593517
3518 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393519}
3520
[email protected]96449d2c2009-11-25 00:01:323521const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3522 if (command_id > kStartPoint && command_id < kNumCommands) {
3523 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3524 }
3525 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3526}
3527
3528// Decode command with its arguments, and call the corresponding GL function.
3529// Note: args is a pointer to the command buffer. As such, it could be changed
3530// by a (malicious) client at any time, so if validation has to happen, it
3531// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143532error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323533 unsigned int command,
3534 unsigned int arg_count,
3535 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143536 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263537 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003538 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
3539 // LOG(INFO), tried VLOG(1), no luck.
[email protected]1d82e822013-04-10 21:32:323540 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" << "cmd: "
[email protected]d2a0e1a2012-08-12 02:25:013541 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193542 }
[email protected]96449d2c2009-11-25 00:01:323543 unsigned int command_index = command - kStartPoint - 1;
3544 if (command_index < arraysize(g_command_info)) {
3545 const CommandInfo& info = g_command_info[command_index];
3546 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3547 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3548 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]b9849abf2009-11-25 19:13:193549 uint32 immediate_data_size =
3550 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323551 switch (command) {
3552 #define GLES2_CMD_OP(name) \
[email protected]ed9f9cd2013-02-27 21:12:353553 case cmds::name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193554 result = Handle ## name( \
3555 immediate_data_size, \
[email protected]ed9f9cd2013-02-27 21:12:353556 *static_cast<const gles2::cmds::name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193557 break; \
[email protected]96449d2c2009-11-25 00:01:323558
3559 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323560 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383561 }
3562 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303563 GLenum error;
3564 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]1d82e822013-04-10 21:32:323565 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003566 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3567 << GetCommandName(command);
[email protected]ab09b612013-03-11 22:11:513568 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193569 }
[email protected]96449d2c2009-11-25 00:01:323570 }
3571 } else {
[email protected]f7a64ee2010-02-01 22:24:143572 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323573 }
[email protected]b9849abf2009-11-25 19:13:193574 } else {
3575 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323576 }
[email protected]a3a93e7b2010-08-28 00:48:563577 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3578 result = current_decoder_error_;
3579 current_decoder_error_ = error::kNoError;
3580 }
[email protected]b9849abf2009-11-25 19:13:193581 return result;
[email protected]96449d2c2009-11-25 00:01:323582}
3583
[email protected]ed9f9cd2013-02-27 21:12:353584void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3585 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503586}
3587
[email protected]ae51d192010-04-27 00:48:033588bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353589 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033590 return false;
3591 }
[email protected]96449d2c2009-11-25 00:01:323592 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033593 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353594 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323595 }
[email protected]ae51d192010-04-27 00:48:033596 return true;
[email protected]96449d2c2009-11-25 00:01:323597}
3598
[email protected]ae51d192010-04-27 00:48:033599bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353600 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033601 return false;
[email protected]96449d2c2009-11-25 00:01:323602 }
[email protected]ae51d192010-04-27 00:48:033603 GLuint service_id = glCreateShader(type);
3604 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353605 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033606 }
3607 return true;
[email protected]96449d2c2009-11-25 00:01:323608}
3609
[email protected]882ba1e22012-03-08 19:02:533610void GLES2DecoderImpl::DoFinish() {
3611 glFinish();
[email protected]22e3f552012-03-13 01:54:193612 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533613}
3614
3615void GLES2DecoderImpl::DoFlush() {
3616 glFlush();
[email protected]22e3f552012-03-13 01:54:193617 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533618}
3619
[email protected]3916c97e2010-02-25 03:20:503620void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453621 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023622 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513623 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533624 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503625 return;
3626 }
[email protected]e259eb412012-10-13 05:47:243627 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453628 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503629}
3630
[email protected]051b1372010-04-12 02:42:083631void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073632 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083633 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033634 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073635 buffer = GetBuffer(client_id);
3636 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353637 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153638 LOG(ERROR) << "glBindBuffer: id not generated by glGenBuffers";
3639 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353640 return;
3641 }
3642
[email protected]b10492f2013-03-08 05:24:073643 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033644 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353645 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073646 buffer = GetBuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573647 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103648 group_->GetIdAllocator(id_namespaces::kBuffers);
3649 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033650 }
[email protected]051b1372010-04-12 02:42:083651 }
[email protected]b10492f2013-03-08 05:24:073652 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3653 if (buffer) {
3654 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513655 LOCAL_SET_GL_ERROR(
3656 GL_INVALID_OPERATION,
3657 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473658 return;
3659 }
[email protected]b10492f2013-03-08 05:24:073660 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473661 }
[email protected]96449d2c2009-11-25 00:01:323662 switch (target) {
3663 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073664 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323665 break;
3666 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073667 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323668 break;
3669 default:
[email protected]a93bb842010-02-16 23:03:473670 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323671 break;
3672 }
[email protected]051b1372010-04-12 02:42:083673 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323674}
3675
[email protected]297ca1c2011-06-20 23:08:463676bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha() {
3677 return (GLES2Util::GetChannelsForFormat(
3678 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3679}
3680
3681bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353682 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453683 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203684 if (framebuffer) {
3685 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463686 }
3687 if (offscreen_target_frame_buffer_.get()) {
3688 return offscreen_target_depth_format_ != 0;
3689 }
3690 return back_buffer_has_depth_;
3691}
3692
3693bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353694 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453695 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203696 if (framebuffer) {
3697 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463698 }
3699 if (offscreen_target_frame_buffer_.get()) {
3700 return offscreen_target_stencil_format_ != 0 ||
3701 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3702 }
3703 return back_buffer_has_stencil_;
3704}
3705
3706void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]88a61bf2012-10-27 13:00:423707 if (clear_state_dirty_) {
[email protected]297ca1c2011-06-20 23:08:463708 glColorMask(
[email protected]e259eb412012-10-13 05:47:243709 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
3710 state_.color_mask_alpha &&
3711 BoundFramebufferHasColorAttachmentWithAlpha());
[email protected]297ca1c2011-06-20 23:08:463712 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]e259eb412012-10-13 05:47:243713 glDepthMask(state_.depth_mask && have_depth);
[email protected]f731b9462012-10-30 00:35:223714 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
[email protected]297ca1c2011-06-20 23:08:463715 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]e259eb412012-10-13 05:47:243716 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423717 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]e259eb412012-10-13 05:47:243718 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423719 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]f731b9462012-10-30 00:35:223720 EnableDisable(
3721 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3722 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
3723 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
3724 EnableDisable(GL_BLEND, state_.enable_flags.blend);
[email protected]88a61bf2012-10-27 13:00:423725 clear_state_dirty_ = false;
[email protected]297ca1c2011-06-20 23:08:463726 }
3727}
3728
[email protected]1868a342012-11-07 15:56:023729GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]b177ae22011-11-01 03:29:113730 return (offscreen_target_frame_buffer_.get()) ?
3731 offscreen_target_frame_buffer_->id() :
[email protected]1868a342012-11-07 15:56:023732 (surface_ ? surface_->GetBackingFrameBufferObject() : 0);
3733}
3734
3735void GLES2DecoderImpl::RestoreState() const {
[email protected]29a4d902013-02-26 20:18:063736 // Restore the Framebuffer first because of bugs in Intel drivers.
3737 // Intel drivers incorrectly clip the viewport settings to
3738 // the size of the current framebuffer object.
3739 RestoreFramebufferBindings();
3740 state_.RestoreState();
3741}
3742
3743void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]1868a342012-11-07 15:56:023744 GLuint service_id = state_.bound_draw_framebuffer ?
3745 state_.bound_draw_framebuffer->service_id() :
3746 GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063747 if (!features().chromium_framebuffer_multisample) {
3748 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
3749 } else {
3750 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
3751 service_id = state_.bound_read_framebuffer ?
3752 state_.bound_read_framebuffer->service_id() :
3753 GetBackbufferServiceId();
3754 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
3755 }
[email protected]70d34263c2013-01-09 00:27:453756 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:063757}
3758
3759void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
3760 GLuint client_id = 0;
3761 if (texture_manager()->GetClientId(service_id, &client_id)) {
[email protected]ed9f9cd2013-02-27 21:12:353762 Texture* texture = GetTexture(client_id);
[email protected]9bc9a2e82013-04-03 03:56:253763 GLenum target = texture->target();
3764 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:063765 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253766 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:063767 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253768 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:063769 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253770 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:063771 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253772 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:063773 RestoreTextureUnitBindings(state_.active_texture_unit);
3774 }
[email protected]70d34263c2013-01-09 00:27:453775}
3776
3777void GLES2DecoderImpl::OnFboChanged() const {
3778 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:513779 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
3780}
3781
3782// Called after the FBO is checked for completeness.
3783void GLES2DecoderImpl::OnUseFramebuffer() const {
3784 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
3785 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:323786 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:513787 glScissor(state_.scissor_x,
3788 state_.scissor_y,
3789 state_.scissor_width,
3790 state_.scissor_height);
3791
3792 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
3793 // it's unclear how this bug works.
3794 glFlush();
3795 }
[email protected]b177ae22011-11-01 03:29:113796}
3797
[email protected]051b1372010-04-12 02:42:083798void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:063799 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:083800 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033801 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:063802 framebuffer = GetFramebuffer(client_id);
3803 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:353804 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153805 LOG(ERROR)
3806 << "glBindFramebuffer: id not generated by glGenFramebuffers";
3807 current_decoder_error_ = error::kGenericError;
3808 return;
[email protected]bf5a8d132011-08-16 08:39:353809 }
3810
[email protected]4d8f0dd2013-03-09 14:37:063811 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:033812 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353813 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:063814 framebuffer = GetFramebuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573815 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103816 group_->GetIdAllocator(id_namespaces::kFramebuffers);
3817 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033818 } else {
[email protected]4d8f0dd2013-03-09 14:37:063819 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:083820 }
[email protected]4d8f0dd2013-03-09 14:37:063821 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083822 }
[email protected]4d8f0dd2013-03-09 14:37:063823 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:303824
3825 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:063826 state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303827 }
3828 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:063829 state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303830 }
[email protected]6217d392010-03-25 22:08:353831
[email protected]88a61bf2012-10-27 13:00:423832 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:463833
[email protected]b177ae22011-11-01 03:29:113834 // If we are rendering to the backbuffer get the FBO id for any simulated
3835 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:063836 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:113837 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:463838 }
[email protected]6217d392010-03-25 22:08:353839
[email protected]051b1372010-04-12 02:42:083840 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:453841 OnFboChanged();
[email protected]86093972010-03-11 00:13:563842}
3843
[email protected]051b1372010-04-12 02:42:083844void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:273845 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:083846 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033847 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:273848 renderbuffer = GetRenderbuffer(client_id);
3849 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:353850 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153851 LOG(ERROR)
3852 << "glBindRenderbuffer: id not generated by glGenRenderbuffers";
3853 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353854 return;
3855 }
3856
[email protected]ee2a79c32013-03-10 03:50:273857 // It's a new id so make a renderbuffer renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:033858 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353859 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:273860 renderbuffer = GetRenderbuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573861 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103862 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
3863 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033864 } else {
[email protected]ee2a79c32013-03-10 03:50:273865 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:083866 }
[email protected]ee2a79c32013-03-10 03:50:273867 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083868 }
[email protected]ee2a79c32013-03-10 03:50:273869 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenerbuffer");
3870 state_.bound_renderbuffer = renderbuffer;
[email protected]051b1372010-04-12 02:42:083871 glBindRenderbufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563872}
3873
[email protected]051b1372010-04-12 02:42:083874void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]02965c22013-03-09 02:40:073875 Texture* texture = NULL;
[email protected]051b1372010-04-12 02:42:083876 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033877 if (client_id != 0) {
[email protected]02965c22013-03-09 02:40:073878 texture = GetTexture(client_id);
3879 if (!texture) {
[email protected]bf5a8d132011-08-16 08:39:353880 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153881 LOG(ERROR) << "glBindTexture: id not generated by glGenTextures";
3882 current_decoder_error_ = error::kGenericError;
3883 return;
[email protected]bf5a8d132011-08-16 08:39:353884 }
3885
[email protected]02965c22013-03-09 02:40:073886 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:033887 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:413888 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:353889 CreateTexture(client_id, service_id);
[email protected]02965c22013-03-09 02:40:073890 texture = GetTexture(client_id);
[email protected]3b1ecc262011-08-03 22:49:573891 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103892 group_->GetIdAllocator(id_namespaces::kTextures);
3893 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033894 }
3895 } else {
[email protected]02965c22013-03-09 02:40:073896 texture = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:083897 }
[email protected]ae51d192010-04-27 00:48:033898
[email protected]1958e0e2010-04-22 05:17:153899 // Check the texture exists
3900 // Check that we are not trying to bind it to a different target.
[email protected]02965c22013-03-09 02:40:073901 if (texture->target() != 0 && texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:513902 LOCAL_SET_GL_ERROR(
3903 GL_INVALID_OPERATION,
3904 "glBindTexture", "texture bound to more than 1 target.");
[email protected]1958e0e2010-04-22 05:17:153905 return;
3906 }
[email protected]02965c22013-03-09 02:40:073907 if (texture->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:513908 LOCAL_SET_GL_ERROR(
3909 GL_INVALID_OPERATION,
3910 "glBindTexture", "illegal target for stream texture.");
[email protected]b0af4f52011-09-28 22:04:423911 return;
3912 }
[email protected]02965c22013-03-09 02:40:073913 LogClientServiceForInfo(texture, client_id, "glBindTexture");
3914 if (texture->target() == 0) {
3915 texture_manager()->SetTarget(texture, target);
[email protected]a93bb842010-02-16 23:03:473916 }
[email protected]02965c22013-03-09 02:40:073917 glBindTexture(target, texture->service_id());
[email protected]32145a92012-12-17 09:01:593918
[email protected]e259eb412012-10-13 05:47:243919 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:503920 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:473921 switch (target) {
3922 case GL_TEXTURE_2D:
[email protected]02965c22013-03-09 02:40:073923 unit.bound_texture_2d = texture;
[email protected]a93bb842010-02-16 23:03:473924 break;
3925 case GL_TEXTURE_CUBE_MAP:
[email protected]02965c22013-03-09 02:40:073926 unit.bound_texture_cube_map = texture;
[email protected]a93bb842010-02-16 23:03:473927 break;
[email protected]61eeb33f2011-07-26 15:30:313928 case GL_TEXTURE_EXTERNAL_OES:
[email protected]02965c22013-03-09 02:40:073929 unit.bound_texture_external_oes = texture;
3930 if (texture->IsStreamTexture()) {
[email protected]b0af4f52011-09-28 22:04:423931 DCHECK(stream_texture_manager_);
3932 StreamTexture* stream_tex =
[email protected]02965c22013-03-09 02:40:073933 stream_texture_manager_->LookupStreamTexture(texture->service_id());
[email protected]b0af4f52011-09-28 22:04:423934 if (stream_tex)
3935 stream_tex->Update();
3936 }
[email protected]61eeb33f2011-07-26 15:30:313937 break;
[email protected]e51bdf32011-11-23 22:21:463938 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]02965c22013-03-09 02:40:073939 unit.bound_texture_rectangle_arb = texture;
[email protected]e51bdf32011-11-23 22:21:463940 break;
[email protected]a93bb842010-02-16 23:03:473941 default:
3942 NOTREACHED(); // Validation should prevent us getting here.
3943 break;
3944 }
3945}
3946
[email protected]07f54fcc2009-12-22 02:46:303947void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243948 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:123949 if (index != 0 ||
3950 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:243951 glDisableVertexAttribArray(index);
3952 }
[email protected]07f54fcc2009-12-22 02:46:303953 } else {
[email protected]ab09b612013-03-11 22:11:513954 LOCAL_SET_GL_ERROR(
3955 GL_INVALID_VALUE,
3956 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303957 }
3958}
3959
[email protected]60f22d32012-12-12 00:31:583960void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
3961 GLsizei numAttachments,
3962 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:353963 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:583964 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
3965
3966 // Validates the attachments. If one of them fails
3967 // the whole command fails.
3968 for (GLsizei i = 0; i < numAttachments; ++i) {
3969 if ((framebuffer &&
3970 !validators_->attachment.IsValid(attachments[i])) ||
3971 (!framebuffer &&
3972 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:513973 LOCAL_SET_GL_ERROR_INVALID_ENUM(
3974 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:583975 return;
3976 }
3977 }
3978
3979 // Marks each one of them as not cleared
3980 for (GLsizei i = 0; i < numAttachments; ++i) {
3981 if (framebuffer) {
3982 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
3983 texture_manager(),
3984 attachments[i],
3985 false);
3986 } else {
3987 switch (attachments[i]) {
3988 case GL_COLOR_EXT:
3989 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
3990 break;
3991 case GL_DEPTH_EXT:
3992 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
3993 case GL_STENCIL_EXT:
3994 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
3995 break;
3996 default:
3997 NOTREACHED();
3998 break;
3999 }
4000 }
4001 }
4002
4003 glDiscardFramebufferEXT(target, numAttachments, attachments);
4004}
4005
[email protected]07f54fcc2009-12-22 02:46:304006void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244007 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304008 glEnableVertexAttribArray(index);
4009 } else {
[email protected]ab09b612013-03-11 22:11:514010 LOCAL_SET_GL_ERROR(
4011 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304012 }
4013}
4014
[email protected]a93bb842010-02-16 23:03:474015void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]02965c22013-03-09 02:40:074016 Texture* texture = GetTextureInfoForTarget(target);
4017 if (!texture ||
4018 !texture_manager()->CanGenerateMipmaps(texture)) {
[email protected]ab09b612013-03-11 22:11:514019 LOCAL_SET_GL_ERROR(
4020 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474021 return;
4022 }
[email protected]38c0a972012-05-12 00:48:024023
[email protected]12d95352012-12-14 07:23:544024 if (target == GL_TEXTURE_CUBE_MAP) {
4025 for (int i = 0; i < 6; ++i) {
4026 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]02965c22013-03-09 02:40:074027 if (!texture_manager()->ClearTextureLevel(this, texture, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514028 LOCAL_SET_GL_ERROR(
4029 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544030 return;
4031 }
4032 }
4033 } else {
[email protected]02965c22013-03-09 02:40:074034 if (!texture_manager()->ClearTextureLevel(this, texture, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514035 LOCAL_SET_GL_ERROR(
4036 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544037 return;
4038 }
[email protected]7687479c2012-05-14 23:54:044039 }
4040
[email protected]ab09b612013-03-11 22:11:514041 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194042 // Workaround for Mac driver bug. In the large scheme of things setting
4043 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564044 // hit so there's probably no need to make this conditional. The bug appears
4045 // to be that if the filtering mode is set to something that doesn't require
4046 // mipmaps for rendering, or is never set to something other than the default,
4047 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154048 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194049 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4050 }
[email protected]a93bb842010-02-16 23:03:474051 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154052 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]02965c22013-03-09 02:40:074053 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]c892a4e12012-05-08 18:20:194054 }
[email protected]ab09b612013-03-11 22:11:514055 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024056 if (error == GL_NO_ERROR) {
[email protected]02965c22013-03-09 02:40:074057 texture_manager()->MarkMipmapsGenerated(texture);
[email protected]38c0a972012-05-12 00:48:024058 }
[email protected]a93bb842010-02-16 23:03:474059}
4060
[email protected]b273e432010-04-12 17:23:584061bool GLES2DecoderImpl::GetHelper(
4062 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584063 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154064 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4065 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434066 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4067 *num_written = 1;
4068 if (params) {
4069 *params = GL_RGBA; // We don't support other formats.
4070 }
4071 return true;
4072 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4073 *num_written = 1;
4074 if (params) {
4075 *params = GL_UNSIGNED_BYTE; // We don't support other types.
4076 }
4077 return true;
4078 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4079 *num_written = 1;
4080 if (params) {
4081 *params = group_->max_fragment_uniform_vectors();
4082 }
4083 return true;
4084 case GL_MAX_VARYING_VECTORS:
4085 *num_written = 1;
4086 if (params) {
4087 *params = group_->max_varying_vectors();
4088 }
4089 return true;
4090 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4091 *num_written = 1;
4092 if (params) {
4093 *params = group_->max_vertex_uniform_vectors();
4094 }
4095 return true;
[email protected]4e8a5b122010-05-08 22:00:104096 }
[email protected]5cb735d2011-10-13 01:37:234097 }
4098 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244099 case GL_MAX_VIEWPORT_DIMS:
4100 if (offscreen_target_frame_buffer_.get()) {
4101 *num_written = 2;
4102 if (params) {
4103 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4104 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4105 }
4106 return true;
4107 }
[email protected]5cb735d2011-10-13 01:37:234108 return false;
[email protected]84afefa2011-10-19 21:45:534109 case GL_MAX_SAMPLES:
4110 *num_written = 1;
4111 if (params) {
4112 params[0] = renderbuffer_manager()->max_samples();
4113 }
4114 return true;
4115 case GL_MAX_RENDERBUFFER_SIZE:
4116 *num_written = 1;
4117 if (params) {
4118 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4119 }
4120 return true;
[email protected]5cb735d2011-10-13 01:37:234121 case GL_MAX_TEXTURE_SIZE:
4122 *num_written = 1;
4123 if (params) {
4124 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4125 }
4126 return true;
4127 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4128 *num_written = 1;
4129 if (params) {
4130 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4131 }
4132 return true;
[email protected]2f143d482013-03-14 18:04:494133 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4134 *num_written = 1;
4135 if (params) {
4136 params[0] = group_->max_color_attachments();
4137 }
4138 return true;
4139 case GL_MAX_DRAW_BUFFERS_ARB:
4140 *num_written = 1;
4141 if (params) {
4142 params[0] = group_->max_draw_buffers();
4143 }
4144 return true;
[email protected]297ca1c2011-06-20 23:08:464145 case GL_ALPHA_BITS:
4146 *num_written = 1;
4147 if (params) {
4148 GLint v = 0;
4149 glGetIntegerv(GL_ALPHA_BITS, &v);
4150 params[0] = BoundFramebufferHasColorAttachmentWithAlpha() ? v : 0;
4151 }
4152 return true;
4153 case GL_DEPTH_BITS:
4154 *num_written = 1;
4155 if (params) {
4156 GLint v = 0;
4157 glGetIntegerv(GL_DEPTH_BITS, &v);
4158 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4159 }
4160 return true;
4161 case GL_STENCIL_BITS:
4162 *num_written = 1;
4163 if (params) {
4164 GLint v = 0;
4165 glGetIntegerv(GL_STENCIL_BITS, &v);
4166 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4167 }
4168 return true;
[email protected]656dcaad2010-05-07 17:18:374169 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114170 *num_written = validators_->compressed_texture_format.GetValues().size();
4171 if (params) {
4172 for (GLint ii = 0; ii < *num_written; ++ii) {
4173 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4174 }
4175 }
[email protected]656dcaad2010-05-07 17:18:374176 return true;
[email protected]b273e432010-04-12 17:23:584177 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4178 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104179 if (params) {
[email protected]302ce6d2011-07-07 23:28:114180 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104181 }
[email protected]b273e432010-04-12 17:23:584182 return true;
4183 case GL_NUM_SHADER_BINARY_FORMATS:
4184 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104185 if (params) {
[email protected]302ce6d2011-07-07 23:28:114186 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104187 }
[email protected]b273e432010-04-12 17:23:584188 return true;
4189 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114190 *num_written = validators_->shader_binary_format.GetValues().size();
4191 if (params) {
4192 for (GLint ii = 0; ii < *num_written; ++ii) {
4193 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4194 }
4195 }
4196 return true;
[email protected]b273e432010-04-12 17:23:584197 case GL_SHADER_COMPILER:
4198 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104199 if (params) {
4200 *params = GL_TRUE;
4201 }
[email protected]b273e432010-04-12 17:23:584202 return true;
[email protected]6b8cf1a2010-05-06 16:13:584203 case GL_ARRAY_BUFFER_BINDING:
4204 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104205 if (params) {
[email protected]e259eb412012-10-13 05:47:244206 if (state_.bound_array_buffer) {
[email protected]4e8a5b122010-05-08 22:00:104207 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244208 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104209 &client_id);
4210 *params = client_id;
4211 } else {
4212 *params = 0;
4213 }
[email protected]6b8cf1a2010-05-06 16:13:584214 }
4215 return true;
4216 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4217 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104218 if (params) {
[email protected]e259eb412012-10-13 05:47:244219 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104220 GLuint client_id = 0;
4221 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254222 state_.vertex_attrib_manager->element_array_buffer()->
4223 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104224 *params = client_id;
4225 } else {
4226 *params = 0;
4227 }
[email protected]6b8cf1a2010-05-06 16:13:584228 }
4229 return true;
4230 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304231 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584232 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104233 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354234 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454235 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204236 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104237 GLuint client_id = 0;
4238 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204239 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304240 *params = client_id;
4241 } else {
4242 *params = 0;
4243 }
4244 }
4245 return true;
[email protected]ebfb73c2012-08-15 02:37:454246 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304247 *num_written = 1;
4248 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354249 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454250 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204251 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304252 GLuint client_id = 0;
4253 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204254 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104255 *params = client_id;
4256 } else {
4257 *params = 0;
4258 }
[email protected]6b8cf1a2010-05-06 16:13:584259 }
4260 return true;
4261 case GL_RENDERBUFFER_BINDING:
4262 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104263 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354264 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204265 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4266 if (renderbuffer) {
[email protected]4e8a5b122010-05-08 22:00:104267 GLuint client_id = 0;
4268 renderbuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204269 renderbuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104270 *params = client_id;
4271 } else {
4272 *params = 0;
4273 }
[email protected]6b8cf1a2010-05-06 16:13:584274 }
4275 return true;
4276 case GL_CURRENT_PROGRAM:
4277 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104278 if (params) {
[email protected]e259eb412012-10-13 05:47:244279 if (state_.current_program) {
[email protected]4e8a5b122010-05-08 22:00:104280 GLuint client_id = 0;
4281 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244282 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104283 *params = client_id;
4284 } else {
4285 *params = 0;
4286 }
[email protected]6b8cf1a2010-05-06 16:13:584287 }
4288 return true;
[email protected]bf835842012-11-19 15:21:514289 case GL_VERTEX_ARRAY_BINDING_OES:
4290 *num_written = 1;
4291 if (params) {
4292 if (state_.vertex_attrib_manager != default_vertex_attrib_manager_) {
4293 GLuint client_id = 0;
4294 vertex_array_manager_->GetClientId(
4295 state_.vertex_attrib_manager->service_id(), &client_id);
4296 *params = client_id;
4297 } else {
4298 *params = 0;
4299 }
4300 }
4301 return true;
[email protected]4e8a5b122010-05-08 22:00:104302 case GL_TEXTURE_BINDING_2D:
4303 *num_written = 1;
4304 if (params) {
[email protected]e259eb412012-10-13 05:47:244305 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]6b8cf1a2010-05-06 16:13:584306 if (unit.bound_texture_2d) {
4307 GLuint client_id = 0;
4308 texture_manager()->GetClientId(
4309 unit.bound_texture_2d->service_id(), &client_id);
4310 *params = client_id;
4311 } else {
4312 *params = 0;
4313 }
[email protected]6b8cf1a2010-05-06 16:13:584314 }
[email protected]4e8a5b122010-05-08 22:00:104315 return true;
4316 case GL_TEXTURE_BINDING_CUBE_MAP:
4317 *num_written = 1;
4318 if (params) {
[email protected]e259eb412012-10-13 05:47:244319 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]6b8cf1a2010-05-06 16:13:584320 if (unit.bound_texture_cube_map) {
4321 GLuint client_id = 0;
4322 texture_manager()->GetClientId(
4323 unit.bound_texture_cube_map->service_id(), &client_id);
4324 *params = client_id;
4325 } else {
4326 *params = 0;
4327 }
[email protected]6b8cf1a2010-05-06 16:13:584328 }
[email protected]4e8a5b122010-05-08 22:00:104329 return true;
[email protected]61eeb33f2011-07-26 15:30:314330 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4331 *num_written = 1;
4332 if (params) {
[email protected]e259eb412012-10-13 05:47:244333 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]61eeb33f2011-07-26 15:30:314334 if (unit.bound_texture_external_oes) {
4335 GLuint client_id = 0;
4336 texture_manager()->GetClientId(
4337 unit.bound_texture_external_oes->service_id(), &client_id);
4338 *params = client_id;
4339 } else {
4340 *params = 0;
4341 }
4342 }
4343 return true;
[email protected]e51bdf32011-11-23 22:21:464344 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4345 *num_written = 1;
4346 if (params) {
[email protected]e259eb412012-10-13 05:47:244347 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]e51bdf32011-11-23 22:21:464348 if (unit.bound_texture_rectangle_arb) {
4349 GLuint client_id = 0;
4350 texture_manager()->GetClientId(
4351 unit.bound_texture_rectangle_arb->service_id(), &client_id);
4352 *params = client_id;
4353 } else {
4354 *params = 0;
4355 }
4356 }
4357 return true;
[email protected]6c75c712012-06-19 15:43:174358 case GL_UNPACK_FLIP_Y_CHROMIUM:
4359 *num_written = 1;
4360 if (params) {
4361 params[0] = unpack_flip_y_;
4362 }
4363 return true;
4364 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4365 *num_written = 1;
4366 if (params) {
4367 params[0] = unpack_premultiply_alpha_;
4368 }
4369 return true;
4370 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4371 *num_written = 1;
4372 if (params) {
4373 params[0] = unpack_unpremultiply_alpha_;
4374 }
4375 return true;
[email protected]b273e432010-04-12 17:23:584376 default:
[email protected]2f143d482013-03-14 18:04:494377 if (pname >= GL_DRAW_BUFFER0_ARB &&
4378 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4379 *num_written = 1;
4380 if (params) {
4381 Framebuffer* framebuffer =
4382 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4383 if (framebuffer) {
4384 params[0] = framebuffer->GetDrawBuffer(pname);
4385 } else { // backbuffer
4386 if (pname == GL_DRAW_BUFFER0_ARB)
4387 params[0] = group_->draw_buffer();
4388 else
4389 params[0] = GL_NONE;
4390 }
4391 }
4392 return true;
4393 }
[email protected]4e8a5b122010-05-08 22:00:104394 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534395 return false;
[email protected]b273e432010-04-12 17:23:584396 }
4397}
4398
[email protected]4e8a5b122010-05-08 22:00:104399bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4400 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264401 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534402 return true;
4403 }
[email protected]4e8a5b122010-05-08 22:00:104404 return GetHelper(pname, NULL, num_values);
4405}
4406
[email protected]b273e432010-04-12 17:23:584407void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4408 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104409 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534410 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554411 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264412 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534413 GetHelper(pname, values.get(), &num_written);
4414 }
[email protected]b273e432010-04-12 17:23:584415 for (GLsizei ii = 0; ii < num_written; ++ii) {
4416 params[ii] = static_cast<GLboolean>(values[ii]);
4417 }
4418 } else {
4419 glGetBooleanv(pname, params);
4420 }
4421}
4422
4423void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4424 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104425 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264426 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534427 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554428 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534429 GetHelper(pname, values.get(), &num_written);
4430 for (GLsizei ii = 0; ii < num_written; ++ii) {
4431 params[ii] = static_cast<GLfloat>(values[ii]);
4432 }
4433 } else {
4434 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584435 }
[email protected]b273e432010-04-12 17:23:584436 }
4437}
4438
4439void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4440 DCHECK(params);
4441 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264442 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534443 !GetHelper(pname, params, &num_written)) {
[email protected]b273e432010-04-12 17:23:584444 glGetIntegerv(pname, params);
4445 }
4446}
4447
[email protected]a0c3e972010-04-21 00:49:134448void GLES2DecoderImpl::DoGetProgramiv(
4449 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424450 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4451 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134452 return;
4453 }
[email protected]df37b9932013-03-08 05:21:424454 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134455}
4456
[email protected]17cfbe0e2013-03-07 01:26:084457void GLES2DecoderImpl::DoGetBufferParameteriv(
4458 GLenum target, GLenum pname, GLint* params) {
4459 Buffer* buffer = GetBufferInfoForTarget(target);
4460 if (!buffer) {
[email protected]ab09b612013-03-11 22:11:514461 LOCAL_SET_GL_ERROR(
[email protected]17cfbe0e2013-03-07 01:26:084462 GL_INVALID_OPERATION, "glGetBufferParameteriv",
4463 "no buffer bound for target");
4464 return;
4465 }
4466 switch (pname) {
4467 case GL_BUFFER_SIZE:
4468 *params = buffer->size();
4469 break;
4470 case GL_BUFFER_USAGE:
4471 *params = buffer->usage();
4472 break;
4473 default:
4474 NOTREACHED();
4475 }
4476}
4477
[email protected]258a3313f2011-10-18 20:13:574478void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424479 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574480 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514481 LOCAL_SET_GL_ERROR(
4482 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574483 return;
4484 }
[email protected]68dcb1f2012-04-07 00:14:564485 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514486 LOCAL_SET_GL_ERROR(
4487 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564488 return;
4489 }
4490 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514491 LOCAL_SET_GL_ERROR(
4492 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564493 return;
4494 }
[email protected]df37b9932013-03-08 05:21:424495 Program* program = GetProgramInfoNotShader(
4496 program_id, "glBindAttribLocation");
4497 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574498 return;
[email protected]558847a2010-03-24 07:02:544499 }
[email protected]df37b9932013-03-08 05:21:424500 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
4501 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574502}
4503
4504error::Error GLES2DecoderImpl::HandleBindAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:354505 uint32 immediate_data_size, const cmds::BindAttribLocation& c) {
[email protected]258a3313f2011-10-18 20:13:574506 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544507 GLuint index = static_cast<GLuint>(c.index);
4508 uint32 name_size = c.data_size;
4509 const char* name = GetSharedMemoryAs<const char*>(
4510 c.name_shm_id, c.name_shm_offset, name_size);
4511 if (name == NULL) {
4512 return error::kOutOfBounds;
4513 }
4514 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574515 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544516 return error::kNoError;
4517}
4518
4519error::Error GLES2DecoderImpl::HandleBindAttribLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:354520 uint32 immediate_data_size, const cmds::BindAttribLocationImmediate& c) {
[email protected]6b8cf1a2010-05-06 16:13:584521 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544522 GLuint index = static_cast<GLuint>(c.index);
4523 uint32 name_size = c.data_size;
4524 const char* name = GetImmediateDataAs<const char*>(
4525 c, name_size, immediate_data_size);
4526 if (name == NULL) {
4527 return error::kOutOfBounds;
4528 }
4529 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574530 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544531 return error::kNoError;
4532}
4533
4534error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:354535 uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) {
[email protected]6b8cf1a2010-05-06 16:13:584536 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544537 GLuint index = static_cast<GLuint>(c.index);
4538 Bucket* bucket = GetBucket(c.name_bucket_id);
4539 if (!bucket || bucket->size() == 0) {
4540 return error::kInvalidArguments;
4541 }
4542 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184543 if (!bucket->GetAsString(&name_str)) {
4544 return error::kInvalidArguments;
4545 }
[email protected]258a3313f2011-10-18 20:13:574546 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544547 return error::kNoError;
4548}
4549
[email protected]2be6abf32012-06-26 00:28:334550void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424551 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334552 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514553 LOCAL_SET_GL_ERROR(
4554 GL_INVALID_VALUE,
4555 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334556 return;
4557 }
4558 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514559 LOCAL_SET_GL_ERROR(
4560 GL_INVALID_OPERATION,
4561 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334562 return;
4563 }
4564 if (location < 0 || static_cast<uint32>(location) >=
4565 (group_->max_fragment_uniform_vectors() +
4566 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514567 LOCAL_SET_GL_ERROR(
4568 GL_INVALID_VALUE,
4569 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334570 return;
4571 }
[email protected]df37b9932013-03-08 05:21:424572 Program* program = GetProgramInfoNotShader(
4573 program_id, "glBindUniformLocationCHROMIUM");
4574 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334575 return;
4576 }
[email protected]df37b9932013-03-08 05:21:424577 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514578 LOCAL_SET_GL_ERROR(
4579 GL_INVALID_VALUE,
4580 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334581 }
4582}
4583
4584error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354585 uint32 immediate_data_size, const cmds::BindUniformLocationCHROMIUM& c) {
[email protected]2be6abf32012-06-26 00:28:334586 GLuint program = static_cast<GLuint>(c.program);
4587 GLint location = static_cast<GLint>(c.location);
4588 uint32 name_size = c.data_size;
4589 const char* name = GetSharedMemoryAs<const char*>(
4590 c.name_shm_id, c.name_shm_offset, name_size);
4591 if (name == NULL) {
4592 return error::kOutOfBounds;
4593 }
4594 String name_str(name, name_size);
4595 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4596 return error::kNoError;
4597}
4598
4599error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMImmediate(
4600 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354601 const cmds::BindUniformLocationCHROMIUMImmediate& c) {
[email protected]2be6abf32012-06-26 00:28:334602 GLuint program = static_cast<GLuint>(c.program);
4603 GLint location = static_cast<GLint>(c.location);
4604 uint32 name_size = c.data_size;
4605 const char* name = GetImmediateDataAs<const char*>(
4606 c, name_size, immediate_data_size);
4607 if (name == NULL) {
4608 return error::kOutOfBounds;
4609 }
4610 String name_str(name, name_size);
4611 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4612 return error::kNoError;
4613}
4614
4615error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4616 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354617 const cmds::BindUniformLocationCHROMIUMBucket& c) {
[email protected]2be6abf32012-06-26 00:28:334618 GLuint program = static_cast<GLuint>(c.program);
4619 GLint location = static_cast<GLint>(c.location);
4620 Bucket* bucket = GetBucket(c.name_bucket_id);
4621 if (!bucket || bucket->size() == 0) {
4622 return error::kInvalidArguments;
4623 }
4624 std::string name_str;
4625 if (!bucket->GetAsString(&name_str)) {
4626 return error::kInvalidArguments;
4627 }
4628 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4629 return error::kNoError;
4630}
4631
[email protected]f7a64ee2010-02-01 22:24:144632error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ed9f9cd2013-02-27 21:12:354633 uint32 immediate_data_size, const cmds::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034634 GLuint client_id = c.shader;
4635 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424636 Shader* shader = GetShader(client_id);
4637 if (shader) {
4638 if (!shader->IsDeleted()) {
4639 glDeleteShader(shader->service_id());
4640 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144641 }
[email protected]ae51d192010-04-27 00:48:034642 } else {
[email protected]ab09b612013-03-11 22:11:514643 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034644 }
[email protected]96449d2c2009-11-25 00:01:324645 }
[email protected]f7a64ee2010-02-01 22:24:144646 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324647}
4648
[email protected]f7a64ee2010-02-01 22:24:144649error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ed9f9cd2013-02-27 21:12:354650 uint32 immediate_data_size, const cmds::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034651 GLuint client_id = c.program;
4652 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424653 Program* program = GetProgram(client_id);
4654 if (program) {
4655 if (!program->IsDeleted()) {
4656 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144657 }
[email protected]ae51d192010-04-27 00:48:034658 } else {
[email protected]ab09b612013-03-11 22:11:514659 LOCAL_SET_GL_ERROR(
4660 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034661 }
[email protected]96449d2c2009-11-25 00:01:324662 }
[email protected]f7a64ee2010-02-01 22:24:144663 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324664}
4665
[email protected]269200b12010-11-18 22:53:064666void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104667 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574668 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104669 for (GLsizei ii = 0; ii < n; ++ii) {
4670 id_allocator->FreeID(ids[ii]);
4671 }
4672}
4673
[email protected]269200b12010-11-18 22:53:064674error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354675 uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104676 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4677 GLsizei n = static_cast<GLsizei>(c.n);
4678 uint32 data_size;
4679 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4680 return error::kOutOfBounds;
4681 }
4682 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4683 c.ids_shm_id, c.ids_shm_offset, data_size);
4684 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514685 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104686 return error::kNoError;
4687 }
4688 if (ids == NULL) {
4689 return error::kOutOfBounds;
4690 }
[email protected]269200b12010-11-18 22:53:064691 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104692 return error::kNoError;
4693}
4694
[email protected]269200b12010-11-18 22:53:064695void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104696 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574697 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104698 if (id_offset == 0) {
4699 for (GLsizei ii = 0; ii < n; ++ii) {
4700 ids[ii] = id_allocator->AllocateID();
4701 }
4702 } else {
4703 for (GLsizei ii = 0; ii < n; ++ii) {
4704 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4705 id_offset = ids[ii] + 1;
4706 }
4707 }
4708}
4709
[email protected]269200b12010-11-18 22:53:064710error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354711 uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104712 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4713 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4714 GLsizei n = static_cast<GLsizei>(c.n);
4715 uint32 data_size;
4716 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4717 return error::kOutOfBounds;
4718 }
4719 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4720 c.ids_shm_id, c.ids_shm_offset, data_size);
4721 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514722 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104723 return error::kNoError;
4724 }
4725 if (ids == NULL) {
4726 return error::kOutOfBounds;
4727 }
[email protected]269200b12010-11-18 22:53:064728 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104729 return error::kNoError;
4730}
4731
[email protected]269200b12010-11-18 22:53:064732void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104733 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574734 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104735 for (GLsizei ii = 0; ii < n; ++ii) {
4736 if (!id_allocator->MarkAsUsed(ids[ii])) {
4737 for (GLsizei jj = 0; jj < ii; ++jj) {
4738 id_allocator->FreeID(ids[jj]);
4739 }
[email protected]ab09b612013-03-11 22:11:514740 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:434741 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4742 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104743 return;
4744 }
4745 }
4746}
4747
[email protected]269200b12010-11-18 22:53:064748error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354749 uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104750 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4751 GLsizei n = static_cast<GLsizei>(c.n);
4752 uint32 data_size;
4753 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4754 return error::kOutOfBounds;
4755 }
4756 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4757 c.ids_shm_id, c.ids_shm_offset, data_size);
4758 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514759 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104760 return error::kNoError;
4761 }
4762 if (ids == NULL) {
4763 return error::kOutOfBounds;
4764 }
[email protected]269200b12010-11-18 22:53:064765 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104766 return error::kNoError;
4767}
4768
[email protected]a7266a92012-06-28 02:11:084769error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444770 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204771 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]e259eb412012-10-13 05:47:244772 UNSHIPPED_TRACE_EVENT_INSTANT2(
4773 "test_gpu", "DoClear",
[email protected]c76faea2013-03-26 07:42:424774 TRACE_EVENT_SCOPE_THREAD,
[email protected]e259eb412012-10-13 05:47:244775 "red", state_.color_clear_red,
4776 "green", state_.color_clear_green);
[email protected]297ca1c2011-06-20 23:08:464777 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:274778 glClear(mask);
4779 }
[email protected]a7266a92012-06-28 02:11:084780 return error::kNoError;
4781}
4782
[email protected]36cef8ce2010-03-16 07:34:454783void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4784 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:034785 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:064786 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4787 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514788 LOCAL_SET_GL_ERROR(
4789 GL_INVALID_OPERATION,
4790 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454791 return;
4792 }
[email protected]ae51d192010-04-27 00:48:034793 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:274794 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:034795 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:274796 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
4797 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514798 LOCAL_SET_GL_ERROR(
4799 GL_INVALID_OPERATION,
4800 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:034801 return;
4802 }
[email protected]ee2a79c32013-03-10 03:50:274803 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:034804 }
[email protected]ab09b612013-03-11 22:11:514805 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:034806 glFramebufferRenderbufferEXT(
4807 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:514808 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:264809 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:274810 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:284811 }
[email protected]4d8f0dd2013-03-09 14:37:064812 if (framebuffer == state_.bound_draw_framebuffer) {
[email protected]88a61bf2012-10-27 13:00:424813 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464814 }
[email protected]81fc9d02013-03-14 23:53:324815 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:284816}
4817
[email protected]3a2e7c7b2010-08-06 01:12:284818void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464819 if (SetCapabilityState(cap, false)) {
4820 glDisable(cap);
4821 }
[email protected]3a2e7c7b2010-08-06 01:12:284822}
4823
4824void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464825 if (SetCapabilityState(cap, true)) {
4826 glEnable(cap);
4827 }
[email protected]3a2e7c7b2010-08-06 01:12:284828}
4829
[email protected]88a61bf2012-10-27 13:00:424830void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4831 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4832 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4833 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:284834}
4835
[email protected]88a61bf2012-10-27 13:00:424836void GLES2DecoderImpl::DoHint(GLenum target, GLenum mode) {
4837 switch (target) {
4838 case GL_GENERATE_MIPMAP_HINT:
4839 state_.hint_generate_mipmap = mode;
4840 break;
4841 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4842 state_.hint_fragment_shader_derivative = mode;
4843 break;
4844 default:
4845 NOTREACHED();
4846 }
4847 glHint(target, mode);
4848}
4849
[email protected]b04e24c2013-01-08 18:35:254850void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:424851 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
4852 state_.sample_coverage_invert = (invert != 0);
4853 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:284854}
4855
[email protected]0d6bfdc2011-11-02 01:32:204856// Assumes framebuffer is complete.
4857void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:064858 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304859 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204860 // bind this to the DRAW point, clear then bind back to READ
4861 // TODO(gman): I don't think there is any guarantee that an FBO that
4862 // is complete on the READ attachment will be complete as a DRAW
4863 // attachment.
4864 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:064865 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:304866 }
[email protected]3a2e7c7b2010-08-06 01:12:284867 GLbitfield clear_bits = 0;
[email protected]4d8f0dd2013-03-09 14:37:064868 if (framebuffer->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
[email protected]297ca1c2011-06-20 23:08:464869 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:204870 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:464871 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:064872 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
4873 1.0f);
[email protected]3a2e7c7b2010-08-06 01:12:284874 glColorMask(true, true, true, true);
4875 clear_bits |= GL_COLOR_BUFFER_BIT;
4876 }
4877
[email protected]4d8f0dd2013-03-09 14:37:064878 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
4879 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284880 glClearStencil(0);
4881 glStencilMask(-1);
4882 clear_bits |= GL_STENCIL_BUFFER_BIT;
4883 }
4884
[email protected]4d8f0dd2013-03-09 14:37:064885 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
4886 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284887 glClearDepth(1.0f);
4888 glDepthMask(true);
4889 clear_bits |= GL_DEPTH_BUFFER_BIT;
4890 }
4891
4892 glDisable(GL_SCISSOR_TEST);
4893 glClear(clear_bits);
4894
[email protected]968351b2011-12-20 08:26:514895 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:064896 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:284897
[email protected]c007aa02010-09-02 22:22:404898 RestoreClearState();
4899
4900 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:064901 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
4902 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:484903 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:064904 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
4905 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:484906 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:404907 }
4908}
4909
4910void GLES2DecoderImpl::RestoreClearState() {
[email protected]88a61bf2012-10-27 13:00:424911 clear_state_dirty_ = true;
[email protected]e259eb412012-10-13 05:47:244912 glClearColor(
4913 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
4914 state_.color_clear_alpha);
4915 glClearStencil(state_.stencil_clear);
4916 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:224917 if (state_.enable_flags.scissor_test) {
[email protected]3a2e7c7b2010-08-06 01:12:284918 glEnable(GL_SCISSOR_TEST);
4919 }
[email protected]36cef8ce2010-03-16 07:34:454920}
4921
4922GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:354923 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:304924 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:204925 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:454926 return GL_FRAMEBUFFER_COMPLETE;
4927 }
[email protected]0d6bfdc2011-11-02 01:32:204928 GLenum completeness = framebuffer->IsPossiblyComplete();
4929 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
4930 return completeness;
4931 }
[email protected]73276522012-11-09 05:50:204932 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:454933}
4934
4935void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:034936 GLenum target, GLenum attachment, GLenum textarget,
4937 GLuint client_texture_id, GLint level) {
[email protected]4d8f0dd2013-03-09 14:37:064938 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4939 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514940 LOCAL_SET_GL_ERROR(
4941 GL_INVALID_OPERATION,
4942 "glFramebufferTexture2D", "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:454943 return;
4944 }
[email protected]ae51d192010-04-27 00:48:034945 GLuint service_id = 0;
[email protected]02965c22013-03-09 02:40:074946 Texture* texture = NULL;
[email protected]ae51d192010-04-27 00:48:034947 if (client_texture_id) {
[email protected]02965c22013-03-09 02:40:074948 texture = GetTexture(client_texture_id);
4949 if (!texture) {
[email protected]ab09b612013-03-11 22:11:514950 LOCAL_SET_GL_ERROR(
4951 GL_INVALID_OPERATION,
4952 "glFramebufferTexture2D", "unknown texture");
[email protected]ae51d192010-04-27 00:48:034953 return;
4954 }
[email protected]02965c22013-03-09 02:40:074955 service_id = texture->service_id();
[email protected]ae51d192010-04-27 00:48:034956 }
[email protected]0d6bfdc2011-11-02 01:32:204957
[email protected]80eb6b52012-01-19 00:14:414958 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:514959 LOCAL_SET_GL_ERROR(
4960 GL_INVALID_VALUE,
4961 "glFramebufferTexture2D", "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:204962 return;
4963 }
4964
[email protected]ab09b612013-03-11 22:11:514965 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferTexture2D");
[email protected]ae51d192010-04-27 00:48:034966 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
[email protected]ab09b612013-03-11 22:11:514967 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferTexture2D");
[email protected]9edc6b22010-12-23 02:00:264968 if (error == GL_NO_ERROR) {
[email protected]4d8f0dd2013-03-09 14:37:064969 framebuffer->AttachTexture(attachment, texture, textarget, level);
[email protected]3a2e7c7b2010-08-06 01:12:284970 }
[email protected]4d8f0dd2013-03-09 14:37:064971 if (framebuffer == state_.bound_draw_framebuffer) {
[email protected]88a61bf2012-10-27 13:00:424972 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464973 }
[email protected]81fc9d02013-03-14 23:53:324974 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:454975}
4976
4977void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
4978 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:064979 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4980 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514981 LOCAL_SET_GL_ERROR(
4982 GL_INVALID_OPERATION,
4983 "glFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454984 return;
4985 }
4986 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:574987 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
4988 GLint type = 0;
4989 GLuint client_id = 0;
4990 glGetFramebufferAttachmentParameterivEXT(
4991 target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
4992 switch (type) {
4993 case GL_RENDERBUFFER: {
4994 renderbuffer_manager()->GetClientId(*params, &client_id);
4995 break;
4996 }
4997 case GL_TEXTURE: {
4998 texture_manager()->GetClientId(*params, &client_id);
4999 break;
5000 }
5001 default:
5002 break;
5003 }
5004 *params = client_id;
5005 }
[email protected]36cef8ce2010-03-16 07:34:455006}
5007
5008void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5009 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355010 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205011 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5012 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515013 LOCAL_SET_GL_ERROR(
5014 GL_INVALID_OPERATION,
5015 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455016 return;
5017 }
[email protected]3a03a8f2011-03-19 00:51:275018 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435019 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5020 *params = renderbuffer->internal_format();
5021 break;
5022 case GL_RENDERBUFFER_WIDTH:
5023 *params = renderbuffer->width();
5024 break;
5025 case GL_RENDERBUFFER_HEIGHT:
5026 *params = renderbuffer->height();
5027 break;
5028 default:
5029 glGetRenderbufferParameterivEXT(target, pname, params);
5030 break;
[email protected]b71f52c2010-06-18 22:20:205031 }
[email protected]36cef8ce2010-03-16 07:34:455032}
5033
[email protected]8e3e0662010-08-23 18:46:305034void GLES2DecoderImpl::DoBlitFramebufferEXT(
5035 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5036 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5037 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445038 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]62e155e2012-10-23 22:43:155039 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:515040 LOCAL_SET_GL_ERROR(
5041 GL_INVALID_OPERATION,
5042 "glBlitFramebufferEXT", "function not available");
[email protected]8e3e0662010-08-23 18:46:305043 }
[email protected]0c16343f2013-03-08 20:40:165044
5045 if (!CheckBoundFramebuffersValid("glBlitFramebufferEXT")) {
5046 return;
5047 }
5048
[email protected]d058bca2012-11-26 10:27:265049 glDisable(GL_SCISSOR_TEST);
[email protected]5094b0f2010-11-09 19:45:245050 if (IsAngle()) {
5051 glBlitFramebufferANGLE(
5052 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5053 } else {
5054 glBlitFramebufferEXT(
5055 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5056 }
[email protected]d058bca2012-11-26 10:27:265057 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
[email protected]c76faea2013-03-26 07:42:425058 UNSHIPPED_TRACE_EVENT_INSTANT1("test_gpu", "DoBlit", TRACE_EVENT_SCOPE_THREAD,
5059 "width", srcX1 - srcX0);
[email protected]8e3e0662010-08-23 18:46:305060}
5061
5062void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
5063 GLenum target, GLsizei samples, GLenum internalformat,
5064 GLsizei width, GLsizei height) {
[email protected]62e155e2012-10-23 22:43:155065 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:515066 LOCAL_SET_GL_ERROR(
5067 GL_INVALID_OPERATION,
5068 "glRenderbufferStorageMultisample", "function not available");
[email protected]8e3e0662010-08-23 18:46:305069 return;
5070 }
[email protected]8e3e0662010-08-23 18:46:305071
[email protected]ed9f9cd2013-02-27 21:12:355072 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205073 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5074 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515075 LOCAL_SET_GL_ERROR(
5076 GL_INVALID_OPERATION,
5077 "glRenderbufferStorageMultisample", "no renderbuffer bound");
[email protected]0d6bfdc2011-11-02 01:32:205078 return;
5079 }
5080
[email protected]84afefa2011-10-19 21:45:535081 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515082 LOCAL_SET_GL_ERROR(
5083 GL_INVALID_VALUE,
5084 "glRenderbufferStorageMultisample", "samples too large");
[email protected]84afefa2011-10-19 21:45:535085 return;
5086 }
5087
5088 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5089 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515090 LOCAL_SET_GL_ERROR(
5091 GL_INVALID_VALUE,
5092 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535093 return;
5094 }
5095
[email protected]7989c9e2013-01-23 06:39:265096 uint32 estimated_size = 0;
5097 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
5098 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515099 LOCAL_SET_GL_ERROR(
5100 GL_OUT_OF_MEMORY,
5101 "glRenderbufferStorageMultsample", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265102 return;
[email protected]8e3e0662010-08-23 18:46:305103 }
5104
[email protected]7989c9e2013-01-23 06:39:265105 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515106 LOCAL_SET_GL_ERROR(
5107 GL_OUT_OF_MEMORY,
5108 "glRenderbufferStorageMultsample", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265109 return;
5110 }
5111
5112 GLenum impl_format = RenderbufferManager::
5113 InternalRenderbufferFormatToImplFormat(internalformat);
[email protected]ab09b612013-03-11 22:11:515114 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisample");
[email protected]866b91c52011-03-23 14:38:085115 if (IsAngle()) {
5116 glRenderbufferStorageMultisampleANGLE(
5117 target, samples, impl_format, width, height);
5118 } else {
5119 glRenderbufferStorageMultisampleEXT(
5120 target, samples, impl_format, width, height);
5121 }
[email protected]ab09b612013-03-11 22:11:515122 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisample");
[email protected]9edc6b22010-12-23 02:00:265123 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515124 // TODO(gman): If renderbuffers tracked which framebuffers they were
5125 // attached to we could just mark those framebuffers as not complete.
5126 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205127 renderbuffer_manager()->SetInfo(
5128 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265129 }
[email protected]8e3e0662010-08-23 18:46:305130}
5131
[email protected]36cef8ce2010-03-16 07:34:455132void GLES2DecoderImpl::DoRenderbufferStorage(
5133 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355134 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205135 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5136 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515137 LOCAL_SET_GL_ERROR(
5138 GL_INVALID_OPERATION,
5139 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455140 return;
5141 }
[email protected]876f6fee2010-08-02 23:10:325142
[email protected]84afefa2011-10-19 21:45:535143 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5144 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515145 LOCAL_SET_GL_ERROR(
5146 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535147 return;
5148 }
5149
[email protected]7989c9e2013-01-23 06:39:265150 uint32 estimated_size = 0;
5151 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
5152 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515153 LOCAL_SET_GL_ERROR(
5154 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265155 return;
5156 }
5157
5158 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515159 LOCAL_SET_GL_ERROR(
5160 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265161 return;
[email protected]b71f52c2010-06-18 22:20:205162 }
[email protected]876f6fee2010-08-02 23:10:325163
[email protected]ab09b612013-03-11 22:11:515164 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265165 glRenderbufferStorageEXT(
5166 target, RenderbufferManager::
5167 InternalRenderbufferFormatToImplFormat(internalformat),
5168 width, height);
[email protected]ab09b612013-03-11 22:11:515169 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265170 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515171 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5172 // we could just mark those framebuffers as not complete.
5173 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205174 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265175 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265176 }
[email protected]36cef8ce2010-03-16 07:34:455177}
5178
[email protected]df37b9932013-03-08 05:21:425179void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385180 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425181 Program* program = GetProgramInfoNotShader(
5182 program_id, "glLinkProgram");
5183 if (!program) {
[email protected]a93bb842010-02-16 23:03:475184 return;
5185 }
[email protected]05afda12011-01-20 00:17:345186
[email protected]df37b9932013-03-08 05:21:425187 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395188 ShaderTranslator* vertex_translator = NULL;
5189 ShaderTranslator* fragment_translator = NULL;
5190 if (use_shader_translator_) {
5191 vertex_translator = vertex_translator_;
5192 fragment_translator = fragment_translator_;
5193 }
[email protected]df37b9932013-03-08 05:21:425194 if (program->Link(shader_manager(),
[email protected]65dfc602012-07-23 20:39:395195 vertex_translator,
5196 fragment_translator,
[email protected]e3932abb2013-03-13 00:01:375197 feature_info_,
5198 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425199 if (program == state_.current_program.get()) {
[email protected]62e155e2012-10-23 22:43:155200 if (workarounds().use_current_program_after_successful_link) {
[email protected]df37b9932013-03-08 05:21:425201 glUseProgram(program->service_id());
[email protected]c2a3caf12012-10-23 19:32:005202 }
[email protected]df37b9932013-03-08 05:21:425203 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545204 }
5205 }
[email protected]07f54fcc2009-12-22 02:46:305206};
5207
[email protected]3916c97e2010-02-25 03:20:505208void GLES2DecoderImpl::DoTexParameterf(
5209 GLenum target, GLenum pname, GLfloat param) {
[email protected]02965c22013-03-09 02:40:075210 Texture* texture = GetTextureInfoForTarget(target);
5211 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515212 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245213 return;
[email protected]07f54fcc2009-12-22 02:46:305214 }
[email protected]cbb22e42011-05-12 23:36:245215
[email protected]02965c22013-03-09 02:40:075216 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505217 "glTexParameterf", GetErrorState(), texture, pname,
5218 static_cast<GLint>(param));
[email protected]07f54fcc2009-12-22 02:46:305219}
5220
[email protected]3916c97e2010-02-25 03:20:505221void GLES2DecoderImpl::DoTexParameteri(
5222 GLenum target, GLenum pname, GLint param) {
[email protected]02965c22013-03-09 02:40:075223 Texture* texture = GetTextureInfoForTarget(target);
5224 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515225 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245226 return;
[email protected]3916c97e2010-02-25 03:20:505227 }
[email protected]cbb22e42011-05-12 23:36:245228
[email protected]02965c22013-03-09 02:40:075229 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505230 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505231}
5232
5233void GLES2DecoderImpl::DoTexParameterfv(
5234 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]02965c22013-03-09 02:40:075235 Texture* texture = GetTextureInfoForTarget(target);
5236 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515237 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245238 return;
[email protected]3916c97e2010-02-25 03:20:505239 }
[email protected]cbb22e42011-05-12 23:36:245240
[email protected]02965c22013-03-09 02:40:075241 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505242 "glTexParameterfv", GetErrorState(), texture, pname,
5243 static_cast<GLint>(params[0]));
[email protected]3916c97e2010-02-25 03:20:505244}
5245
5246void GLES2DecoderImpl::DoTexParameteriv(
5247 GLenum target, GLenum pname, const GLint* params) {
[email protected]02965c22013-03-09 02:40:075248 Texture* texture = GetTextureInfoForTarget(target);
5249 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515250 LOCAL_SET_GL_ERROR(
5251 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245252 return;
[email protected]3916c97e2010-02-25 03:20:505253 }
[email protected]cbb22e42011-05-12 23:36:245254
[email protected]02965c22013-03-09 02:40:075255 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505256 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505257}
5258
[email protected]939e7362010-05-13 20:49:105259bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]e259eb412012-10-13 05:47:245260 if (!state_.current_program) {
[email protected]ad84a3a2012-06-08 21:42:435261 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515262 LOCAL_SET_GL_ERROR(
5263 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435264 return false;
[email protected]939e7362010-05-13 20:49:105265 }
[email protected]e259eb412012-10-13 05:47:245266 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515267 LOCAL_SET_GL_ERROR(
5268 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105269 return false;
5270 }
5271 return true;
5272}
5273
5274bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5275 GLint location, const char* function_name) {
5276 if (!CheckCurrentProgram(function_name)) {
5277 return false;
5278 }
5279 return location != -1;
5280}
5281
[email protected]476ccb72012-12-06 15:52:525282namespace {
5283
5284static const GLenum valid_int_vec1_types_list[] = {
5285 GL_INT,
5286 GL_BOOL,
5287 GL_SAMPLER_2D,
5288 GL_SAMPLER_2D_RECT_ARB,
5289 GL_SAMPLER_CUBE,
5290 GL_SAMPLER_EXTERNAL_OES,
5291};
5292
5293static const GLenum valid_int_vec2_types_list[] = {
5294 GL_INT_VEC2,
5295 GL_BOOL_VEC2,
5296};
5297
5298static const GLenum valid_int_vec3_types_list[] = {
5299 GL_INT_VEC3,
5300 GL_BOOL_VEC3,
5301};
5302
5303static const GLenum valid_int_vec4_types_list[] = {
5304 GL_INT_VEC4,
5305 GL_BOOL_VEC4,
5306};
5307
5308static const GLenum valid_float_vec1_types_list[] = {
5309 GL_FLOAT,
5310 GL_BOOL,
5311};
5312
5313static const GLenum valid_float_vec2_types_list[] = {
5314 GL_FLOAT_VEC2,
5315 GL_BOOL_VEC2,
5316};
5317
5318static const GLenum valid_float_vec3_types_list[] = {
5319 GL_FLOAT_VEC3,
5320 GL_BOOL_VEC3,
5321};
5322
5323static const GLenum valid_float_vec4_types_list[] = {
5324 GL_FLOAT_VEC4,
5325 GL_BOOL_VEC4,
5326};
5327
5328static const GLenum valid_float_mat2_types_list[] = {
5329 GL_FLOAT_MAT2,
5330};
5331
5332static const GLenum valid_float_mat3_types_list[] = {
5333 GL_FLOAT_MAT3,
5334};
5335
5336static const GLenum valid_float_mat4_types_list[] = {
5337 GL_FLOAT_MAT4,
5338};
5339
5340static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec1_base_info = {
5341 valid_int_vec1_types_list,
5342 arraysize(valid_int_vec1_types_list),
5343};
5344
5345static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec2_base_info = {
5346 valid_int_vec2_types_list,
5347 arraysize(valid_int_vec2_types_list),
5348};
5349
5350static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec3_base_info = {
5351 valid_int_vec3_types_list,
5352 arraysize(valid_int_vec3_types_list),
5353};
5354
5355static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec4_base_info = {
5356 valid_int_vec4_types_list,
5357 arraysize(valid_int_vec4_types_list),
5358};
5359
5360static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec1_base_info = {
5361 valid_float_vec1_types_list,
5362 arraysize(valid_float_vec1_types_list),
5363};
5364
5365static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec2_base_info = {
5366 valid_float_vec2_types_list,
5367 arraysize(valid_float_vec2_types_list),
5368};
5369
5370static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec3_base_info = {
5371 valid_float_vec3_types_list,
5372 arraysize(valid_float_vec3_types_list),
5373};
5374
5375static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec4_base_info = {
5376 valid_float_vec4_types_list,
5377 arraysize(valid_float_vec4_types_list),
5378};
5379
5380static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat2_base_info = {
5381 valid_float_mat2_types_list,
5382 arraysize(valid_float_mat2_types_list),
5383};
5384
5385static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat3_base_info = {
5386 valid_float_mat3_types_list,
5387 arraysize(valid_float_mat3_types_list),
5388};
5389
5390static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat4_base_info = {
5391 valid_float_mat4_types_list,
5392 arraysize(valid_float_mat4_types_list),
5393};
5394
5395} // anonymous namespace.
5396
[email protected]43c2f1f2011-03-25 18:35:365397bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:125398 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:525399 const GLES2DecoderImpl::BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:125400 GLint* real_location, GLenum* type, GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365401 DCHECK(type);
5402 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125403 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525404
[email protected]1b0a6752012-02-22 03:44:125405 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105406 return false;
5407 }
[email protected]43c2f1f2011-03-25 18:35:365408 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355409 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245410 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125411 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365412 if (!info) {
[email protected]ab09b612013-03-11 22:11:515413 LOCAL_SET_GL_ERROR(
5414 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105415 return false;
5416 }
[email protected]476ccb72012-12-06 15:52:525417 bool okay = false;
5418 for (size_t ii = 0; ii < base_info.num_valid_types; ++ii) {
5419 if (base_info.valid_types[ii] == info->type) {
5420 okay = true;
5421 break;
5422 }
5423 }
5424 if (!okay) {
[email protected]ab09b612013-03-11 22:11:515425 LOCAL_SET_GL_ERROR(
5426 GL_INVALID_OPERATION, function_name,
5427 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525428 return false;
5429 }
[email protected]43c2f1f2011-03-25 18:35:365430 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515431 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435432 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365433 return false;
5434 }
5435 *count = std::min(info->size - array_index, *count);
5436 if (*count <= 0) {
5437 return false;
5438 }
5439 *type = info->type;
[email protected]939e7362010-05-13 20:49:105440 return true;
5441}
5442
[email protected]1b0a6752012-02-22 03:44:125443void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5444 GLenum type = 0;
5445 GLsizei count = 1;
5446 GLint real_location = -1;
5447 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525448 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5449 &real_location, &type, &count)) {
[email protected]3916c97e2010-02-25 03:20:505450 return;
5451 }
[email protected]e259eb412012-10-13 05:47:245452 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025453 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515454 LOCAL_SET_GL_ERROR(
5455 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465456 return;
5457 }
[email protected]1b0a6752012-02-22 03:44:125458 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505459}
5460
5461void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125462 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365463 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125464 GLint real_location = -1;
5465 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525466 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5467 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365468 return;
5469 }
[email protected]74727112012-06-13 21:18:085470 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5471 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245472 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025473 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515474 LOCAL_SET_GL_ERROR(
5475 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465476 return;
5477 }
[email protected]43c2f1f2011-03-25 18:35:365478 }
[email protected]1b0a6752012-02-22 03:44:125479 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505480}
5481
[email protected]939e7362010-05-13 20:49:105482void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125483 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365484 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125485 GLint real_location = -1;
5486 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525487 fake_location, "glUniform1fv", valid_float_vec1_base_info,
5488 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105489 return;
5490 }
5491 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:555492 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:105493 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535494 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105495 }
[email protected]1b0a6752012-02-22 03:44:125496 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105497 } else {
[email protected]1b0a6752012-02-22 03:44:125498 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105499 }
5500}
5501
5502void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125503 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365504 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125505 GLint real_location = -1;
5506 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525507 fake_location, "glUniform2fv", valid_float_vec2_base_info,
5508 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105509 return;
5510 }
5511 if (type == GL_BOOL_VEC2) {
5512 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:555513 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105514 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535515 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105516 }
[email protected]1b0a6752012-02-22 03:44:125517 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105518 } else {
[email protected]1b0a6752012-02-22 03:44:125519 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105520 }
5521}
5522
5523void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125524 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365525 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125526 GLint real_location = -1;
5527 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525528 fake_location, "glUniform3fv", valid_float_vec3_base_info,
5529 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105530 return;
5531 }
5532 if (type == GL_BOOL_VEC3) {
5533 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:555534 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105535 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535536 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105537 }
[email protected]1b0a6752012-02-22 03:44:125538 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105539 } else {
[email protected]1b0a6752012-02-22 03:44:125540 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105541 }
5542}
5543
5544void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125545 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365546 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125547 GLint real_location = -1;
5548 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525549 fake_location, "glUniform4fv", valid_float_vec4_base_info,
5550 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105551 return;
5552 }
5553 if (type == GL_BOOL_VEC4) {
5554 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:555555 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105556 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535557 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105558 }
[email protected]1b0a6752012-02-22 03:44:125559 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105560 } else {
[email protected]1b0a6752012-02-22 03:44:125561 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105562 }
5563}
5564
[email protected]43c2f1f2011-03-25 18:35:365565void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125566 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365567 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125568 GLint real_location = -1;
5569 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525570 fake_location, "glUniform2iv", valid_int_vec2_base_info,
5571 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365572 return;
5573 }
[email protected]1b0a6752012-02-22 03:44:125574 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365575}
5576
5577void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125578 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365579 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125580 GLint real_location = -1;
5581 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525582 fake_location, "glUniform3iv", valid_int_vec3_base_info,
5583 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365584 return;
5585 }
[email protected]1b0a6752012-02-22 03:44:125586 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365587}
5588
5589void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125590 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365591 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125592 GLint real_location = -1;
5593 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525594 fake_location, "glUniform4iv", valid_int_vec4_base_info,
5595 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365596 return;
5597 }
[email protected]1b0a6752012-02-22 03:44:125598 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365599}
5600
5601void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:125602 GLint fake_location, GLsizei count, GLboolean transpose,
5603 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365604 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125605 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365606 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525607 fake_location, "glUniformMatrix2fv", valid_float_mat2_base_info,
5608 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365609 return;
5610 }
[email protected]1b0a6752012-02-22 03:44:125611 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365612}
5613
5614void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:125615 GLint fake_location, GLsizei count, GLboolean transpose,
5616 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365617 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125618 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365619 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525620 fake_location, "glUniformMatrix3fv", valid_float_mat3_base_info,
5621 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365622 return;
5623 }
[email protected]1b0a6752012-02-22 03:44:125624 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365625}
5626
5627void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:125628 GLint fake_location, GLsizei count, GLboolean transpose,
5629 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365630 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125631 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365632 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525633 fake_location, "glUniformMatrix4fv", valid_float_mat4_base_info,
5634 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365635 return;
5636 }
[email protected]1b0a6752012-02-22 03:44:125637 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365638}
5639
[email protected]df37b9932013-03-08 05:21:425640void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:035641 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:425642 Program* program = NULL;
5643 if (program_id) {
5644 program = GetProgramInfoNotShader(program_id, "glUseProgram");
5645 if (!program) {
[email protected]ae51d192010-04-27 00:48:035646 return;
5647 }
[email protected]df37b9932013-03-08 05:21:425648 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:505649 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:515650 LOCAL_SET_GL_ERROR(
5651 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:505652 return;
5653 }
[email protected]df37b9932013-03-08 05:21:425654 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:505655 }
[email protected]e259eb412012-10-13 05:47:245656 if (state_.current_program) {
5657 program_manager()->UnuseProgram(shader_manager(), state_.current_program);
[email protected]ca488e12010-12-13 20:06:145658 }
[email protected]df37b9932013-03-08 05:21:425659 state_.current_program = program;
5660 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:545661 glUseProgram(service_id);
[email protected]e259eb412012-10-13 05:47:245662 if (state_.current_program) {
5663 program_manager()->UseProgram(state_.current_program);
[email protected]ca488e12010-12-13 20:06:145664 }
[email protected]3916c97e2010-02-25 03:20:505665}
5666
[email protected]ab09b612013-03-11 22:11:515667void GLES2DecoderImpl::RenderWarning(
5668 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:325669 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015670}
5671
[email protected]ab09b612013-03-11 22:11:515672void GLES2DecoderImpl::PerformanceWarning(
5673 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:505674 logger_.LogMessage(filename, line,
5675 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015676}
5677
[email protected]df37b9932013-03-08 05:21:425678void GLES2DecoderImpl::ForceCompileShaderIfPending(Shader* shader) {
5679 if (shader->compilation_status() ==
[email protected]ed9f9cd2013-02-27 21:12:355680 Shader::PENDING_DEFERRED_COMPILE) {
[email protected]c447acd2012-07-23 23:48:415681 ShaderTranslator* translator = NULL;
5682 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:425683 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]c447acd2012-07-23 23:48:415684 vertex_translator_.get() : fragment_translator_.get();
5685 }
5686 // We know there will be no errors, because we only defer compilation on
5687 // shaders that were previously compiled successfully.
[email protected]df37b9932013-03-08 05:21:425688 program_manager()->ForceCompileShader(shader->deferred_compilation_source(),
5689 shader,
[email protected]c447acd2012-07-23 23:48:415690 translator,
5691 feature_info_);
5692 }
5693}
5694
[email protected]ef526492010-06-02 23:12:255695bool GLES2DecoderImpl::SetBlackTextureForNonRenderableTextures() {
[email protected]e259eb412012-10-13 05:47:245696 DCHECK(state_.current_program);
[email protected]ef526492010-06-02 23:12:255697 // Only check if there are some unrenderable textures.
5698 if (!texture_manager()->HaveUnrenderableTextures()) {
5699 return false;
5700 }
5701 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:355702 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245703 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505704 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355705 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245706 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505707 DCHECK(uniform_info);
5708 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5709 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025710 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245711 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]02965c22013-03-09 02:40:075712 Texture* texture =
[email protected]61eeb33f2011-07-26 15:30:315713 texture_unit.GetInfoForSamplerType(uniform_info->type);
[email protected]02965c22013-03-09 02:40:075714 if (!texture || !texture_manager()->CanRender(texture)) {
[email protected]ef526492010-06-02 23:12:255715 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:505716 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5717 glBindTexture(
[email protected]61eeb33f2011-07-26 15:30:315718 GetBindTargetForSamplerType(uniform_info->type),
[email protected]00f893d2010-08-24 18:55:495719 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:515720 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:015721 std::string("texture bound to texture unit ") +
5722 base::IntToString(texture_unit_index) +
5723 " is not renderable. It maybe non-power-of-2 and have "
5724 " incompatible texture filtering or is not "
5725 "'texture complete'");
[email protected]3916c97e2010-02-25 03:20:505726 }
5727 }
5728 // else: should this be an error?
5729 }
5730 }
[email protected]ef526492010-06-02 23:12:255731 return textures_set;
[email protected]3916c97e2010-02-25 03:20:505732}
5733
5734void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() {
[email protected]e259eb412012-10-13 05:47:245735 DCHECK(state_.current_program);
[email protected]ed9f9cd2013-02-27 21:12:355736 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245737 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505738 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355739 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245740 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505741 DCHECK(uniform_info);
5742 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5743 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025744 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245745 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]02965c22013-03-09 02:40:075746 Texture* texture = uniform_info->type == GL_SAMPLER_2D ?
5747 texture_unit.bound_texture_2d :
5748 texture_unit.bound_texture_cube_map;
5749 if (!texture || !texture_manager()->CanRender(texture)) {
[email protected]3916c97e2010-02-25 03:20:505750 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5751 // Get the texture info that was previously bound here.
[email protected]02965c22013-03-09 02:40:075752 texture = texture_unit.bind_target == GL_TEXTURE_2D ?
[email protected]3916c97e2010-02-25 03:20:505753 texture_unit.bound_texture_2d :
5754 texture_unit.bound_texture_cube_map;
5755 glBindTexture(texture_unit.bind_target,
[email protected]02965c22013-03-09 02:40:075756 texture ? texture->service_id() : 0);
[email protected]3916c97e2010-02-25 03:20:505757 }
5758 }
5759 }
5760 }
5761 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:245762 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:305763}
5764
[email protected]0d6bfdc2011-11-02 01:32:205765bool GLES2DecoderImpl::ClearUnclearedTextures() {
5766 // Only check if there are some uncleared textures.
5767 if (!texture_manager()->HaveUnsafeTextures()) {
5768 return true;
5769 }
5770
5771 // 1: Check all textures we are about to render with.
[email protected]e259eb412012-10-13 05:47:245772 if (state_.current_program) {
[email protected]ed9f9cd2013-02-27 21:12:355773 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245774 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:205775 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355776 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245777 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:205778 DCHECK(uniform_info);
5779 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5780 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025781 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245782 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]02965c22013-03-09 02:40:075783 Texture* texture =
[email protected]0d6bfdc2011-11-02 01:32:205784 texture_unit.GetInfoForSamplerType(uniform_info->type);
[email protected]02965c22013-03-09 02:40:075785 if (texture && !texture->SafeToRenderFrom()) {
5786 if (!texture_manager()->ClearRenderableLevels(this, texture)) {
[email protected]0d6bfdc2011-11-02 01:32:205787 return false;
5788 }
5789 }
5790 }
5791 }
5792 }
5793 }
5794 return true;
5795}
5796
[email protected]c6aef902012-02-14 03:31:425797bool GLES2DecoderImpl::IsDrawValid(
[email protected]ad84a3a2012-06-08 21:42:435798 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
[email protected]689fa1c52010-06-09 18:35:035799 // NOTE: We specifically do not check current_program->IsValid() because
5800 // it could never be invalid since glUseProgram would have failed. While
5801 // glLinkProgram could later mark the program as invalid the previous
5802 // valid program will still function if it is still the current program.
[email protected]e259eb412012-10-13 05:47:245803 if (!state_.current_program) {
[email protected]3916c97e2010-02-25 03:20:505804 // The program does not exist.
5805 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:515806 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:505807 return false;
5808 }
[email protected]c6aef902012-02-14 03:31:425809
[email protected]17cfbe0e2013-03-07 01:26:085810 return state_.vertex_attrib_manager->ValidateBindings(
5811 function_name,
5812 this,
5813 feature_info_.get(),
5814 state_.current_program,
5815 max_vertex_accessed,
5816 primcount);
[email protected]b1122982010-05-17 23:04:245817}
5818
[email protected]c13e1da62011-09-09 21:48:305819bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:435820 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:305821 DCHECK(simulated);
5822 *simulated = false;
5823
[email protected]876f6fee2010-08-02 23:10:325824 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:305825 return true;
[email protected]876f6fee2010-08-02 23:10:325826
[email protected]ac77603c72013-03-08 13:52:065827 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:355828 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:245829 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:245830 bool attrib_0_used =
5831 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:065832 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:305833 return true;
[email protected]b1122982010-05-17 23:04:245834 }
5835
[email protected]b1122982010-05-17 23:04:245836 // Make a buffer with a single repeated vec4 value enough to
5837 // simulate the constant value that is supposed to be here.
5838 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:305839 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:475840 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:305841
5842 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:475843 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305844 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:515845 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305846 return false;
5847 }
5848
[email protected]ab09b612013-03-11 22:11:515849 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:015850 "Attribute 0 is disabled. This has signficant performance penalty");
5851
[email protected]ab09b612013-03-11 22:11:515852 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:305853 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
5854
[email protected]8f0b86c2f2012-04-10 05:48:285855 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
5856 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:495857 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305858 GLenum error = glGetError();
5859 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:515860 LOCAL_SET_GL_ERROR(
5861 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305862 return false;
5863 }
[email protected]fc753442011-02-04 19:49:495864 }
[email protected]af6380962012-11-29 23:24:135865
5866 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:285867 if (new_buffer ||
5868 (attrib_0_used &&
5869 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:135870 (value.v[0] != attrib_0_value_.v[0] ||
5871 value.v[1] != attrib_0_value_.v[1] ||
5872 value.v[2] != attrib_0_value_.v[2] ||
5873 value.v[3] != attrib_0_value_.v[3])))) {
5874 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:495875 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
5876 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:135877 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:245878 attrib_0_size_ = size_needed;
5879 }
5880
5881 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
5882
[email protected]ac77603c72013-03-08 13:52:065883 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:425884 glVertexAttribDivisorANGLE(0, 0);
5885
[email protected]c13e1da62011-09-09 21:48:305886 *simulated = true;
[email protected]b1122982010-05-17 23:04:245887 return true;
[email protected]b1122982010-05-17 23:04:245888}
5889
[email protected]ac77603c72013-03-08 13:52:065890void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib_index) {
5891 const VertexAttrib* attrib =
5892 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
5893 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
5894 Buffer* buffer = attrib->buffer();
[email protected]b10492f2013-03-08 05:24:075895 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
[email protected]b1122982010-05-17 23:04:245896 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:065897 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
5898 attrib->gl_stride(), ptr);
5899 if (attrib->divisor())
5900 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:245901 glBindBuffer(
5902 GL_ARRAY_BUFFER,
5903 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:285904
[email protected]265f8992012-07-20 01:03:145905 // Never touch vertex attribute 0's state (in particular, never
5906 // disable it) when running on desktop GL because it will never be
5907 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:065908 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:145909 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:065910 if (attrib->enabled()) {
5911 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:145912 } else {
[email protected]ac77603c72013-03-08 13:52:065913 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:145914 }
[email protected]43410e92012-04-20 17:06:285915 }
[email protected]b1122982010-05-17 23:04:245916}
[email protected]07f54fcc2009-12-22 02:46:305917
[email protected]8fbedc02010-11-18 18:43:405918bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:435919 const char* function_name,
[email protected]c6aef902012-02-14 03:31:425920 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:405921 DCHECK(simulated);
5922 *simulated = false;
5923 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
5924 return true;
5925
[email protected]e259eb412012-10-13 05:47:245926 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:405927 return true;
5928 }
5929
[email protected]ab09b612013-03-11 22:11:515930 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:015931 "GL_FIXED attributes have a signficant performance penalty");
5932
[email protected]8fbedc02010-11-18 18:43:405933 // NOTE: we could be smart and try to check if a buffer is used
5934 // twice in 2 different attribs, find the overlapping parts and therefore
5935 // duplicate the minimum amount of data but this whole code path is not meant
5936 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
5937 // tests so we just add to the buffer attrib used.
5938
[email protected]c13e1da62011-09-09 21:48:305939 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:065940 const VertexAttribManager::VertexAttribList& enabled_attribs =
5941 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
5942 for (VertexAttribManager::VertexAttribList::const_iterator it =
5943 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
5944 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:355945 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:065946 state_.current_program->GetAttribInfoByLocation(attrib->index());
5947 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
5948 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:425949 GLuint num_vertices = max_accessed + 1;
5950 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:515951 LOCAL_SET_GL_ERROR(
5952 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425953 return false;
5954 }
[email protected]8fbedc02010-11-18 18:43:405955 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:065956 attrib->CanAccess(max_accessed) &&
5957 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:475958 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:065959 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:475960 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:515961 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435962 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405963 return false;
5964 }
5965 }
5966 }
5967
[email protected]3aad1a32012-09-07 20:54:475968 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
5969 uint32 size_needed = 0;
5970 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305971 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:515972 LOCAL_SET_GL_ERROR(
5973 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405974 return false;
5975 }
5976
[email protected]ab09b612013-03-11 22:11:515977 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:405978
5979 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:305980 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:405981 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305982 GLenum error = glGetError();
5983 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:515984 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435985 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:305986 return false;
5987 }
[email protected]8fbedc02010-11-18 18:43:405988 }
5989
5990 // Copy the elements and convert to float
5991 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:065992 for (VertexAttribManager::VertexAttribList::const_iterator it =
5993 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
5994 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:355995 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:065996 state_.current_program->GetAttribInfoByLocation(attrib->index());
5997 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:425998 max_vertex_accessed);
5999 GLuint num_vertices = max_accessed + 1;
6000 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516001 LOCAL_SET_GL_ERROR(
6002 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426003 return false;
6004 }
[email protected]8fbedc02010-11-18 18:43:406005 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066006 attrib->CanAccess(max_accessed) &&
6007 attrib->type() == GL_FIXED) {
6008 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:406009 int size = num_elements * num_vertices;
[email protected]40d90a22013-04-09 03:39:556010 scoped_ptr<float[]> data(new float[size]);
[email protected]8fbedc02010-11-18 18:43:406011 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:066012 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:406013 const int32* end = src + num_elements;
6014 float* dst = data.get();
6015 while (src != end) {
6016 *dst++ = static_cast<float>(*src++) / 65536.0f;
6017 }
6018 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
6019 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066020 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406021 reinterpret_cast<GLvoid*>(offset));
6022 offset += size;
6023 }
6024 }
6025 *simulated = true;
6026 return true;
6027}
6028
6029void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6030 // There's no need to call glVertexAttribPointer because we shadow all the
6031 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246032 glBindBuffer(
6033 GL_ARRAY_BUFFER,
6034 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0);
[email protected]8fbedc02010-11-18 18:43:406035}
6036
[email protected]ad84a3a2012-06-08 21:42:436037error::Error GLES2DecoderImpl::DoDrawArrays(
6038 const char* function_name,
6039 bool instanced,
6040 GLenum mode,
6041 GLint first,
6042 GLsizei count,
6043 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:086044 if (ShouldDeferDraws())
6045 return error::kDeferCommandUntilLater;
[email protected]38d139d2011-07-14 00:38:436046 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516047 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436048 return error::kNoError;
6049 }
6050 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516051 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436052 return error::kNoError;
6053 }
[email protected]c6aef902012-02-14 03:31:426054 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516055 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426056 return error::kNoError;
6057 }
[email protected]ad84a3a2012-06-08 21:42:436058 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436059 return error::kNoError;
6060 }
6061 // We have to check this here because the prototype for glDrawArrays
6062 // is GLint not GLsizei.
6063 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516064 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436065 return error::kNoError;
6066 }
6067
[email protected]c6aef902012-02-14 03:31:426068 if (count == 0 || (instanced && primcount == 0)) {
[email protected]ab09b612013-03-11 22:11:516069 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436070 return error::kNoError;
6071 }
6072
6073 GLuint max_vertex_accessed = first + count - 1;
[email protected]ad84a3a2012-06-08 21:42:436074 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206075 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516076 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206077 return error::kNoError;
6078 }
[email protected]c13e1da62011-09-09 21:48:306079 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436080 if (!SimulateAttrib0(
6081 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306082 return error::kNoError;
6083 }
[email protected]38d139d2011-07-14 00:38:436084 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436085 if (SimulateFixedAttribs(
6086 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6087 primcount)) {
[email protected]38d139d2011-07-14 00:38:436088 bool textures_set = SetBlackTextureForNonRenderableTextures();
6089 ApplyDirtyState();
[email protected]c6aef902012-02-14 03:31:426090 if (!instanced) {
6091 glDrawArrays(mode, first, count);
6092 } else {
6093 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6094 }
[email protected]22e3f552012-03-13 01:54:196095 ProcessPendingQueries();
[email protected]38d139d2011-07-14 00:38:436096 if (textures_set) {
6097 RestoreStateForNonRenderableTextures();
6098 }
6099 if (simulated_fixed_attribs) {
6100 RestoreStateForSimulatedFixedAttribs();
6101 }
6102 }
6103 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286104 RestoreStateForAttrib(0);
[email protected]38d139d2011-07-14 00:38:436105 }
[email protected]38d139d2011-07-14 00:38:436106 }
6107 return error::kNoError;
6108}
6109
[email protected]c6aef902012-02-14 03:31:426110error::Error GLES2DecoderImpl::HandleDrawArrays(
[email protected]ed9f9cd2013-02-27 21:12:356111 uint32 immediate_data_size, const cmds::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:436112 return DoDrawArrays("glDrawArrays",
6113 false,
[email protected]c6aef902012-02-14 03:31:426114 static_cast<GLenum>(c.mode),
6115 static_cast<GLint>(c.first),
6116 static_cast<GLsizei>(c.count),
6117 0);
6118}
6119
6120error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356121 uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156122 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516123 LOCAL_SET_GL_ERROR(
6124 GL_INVALID_OPERATION,
6125 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426126 return error::kNoError;
6127 }
[email protected]ad84a3a2012-06-08 21:42:436128 return DoDrawArrays("glDrawArraysIntancedANGLE",
6129 true,
[email protected]c6aef902012-02-14 03:31:426130 static_cast<GLenum>(c.mode),
6131 static_cast<GLint>(c.first),
6132 static_cast<GLsizei>(c.count),
6133 static_cast<GLsizei>(c.primcount));
6134}
6135
[email protected]ad84a3a2012-06-08 21:42:436136error::Error GLES2DecoderImpl::DoDrawElements(
6137 const char* function_name,
6138 bool instanced,
6139 GLenum mode,
6140 GLsizei count,
6141 GLenum type,
6142 int32 offset,
6143 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:086144 if (ShouldDeferDraws())
6145 return error::kDeferCommandUntilLater;
[email protected]e259eb412012-10-13 05:47:246146 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516147 LOCAL_SET_GL_ERROR(
6148 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296149 return error::kNoError;
6150 }
6151
[email protected]8eee29c2010-04-29 03:38:296152 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516153 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296154 return error::kNoError;
6155 }
6156 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516157 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296158 return error::kNoError;
6159 }
[email protected]9438b012010-06-15 22:55:056160 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516161 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296162 return error::kNoError;
6163 }
[email protected]9438b012010-06-15 22:55:056164 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516165 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296166 return error::kNoError;
6167 }
[email protected]c6aef902012-02-14 03:31:426168 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516169 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426170 return error::kNoError;
6171 }
[email protected]8eee29c2010-04-29 03:38:296172
[email protected]ad84a3a2012-06-08 21:42:436173 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276174 return error::kNoError;
6175 }
6176
[email protected]c6aef902012-02-14 03:31:426177 if (count == 0 || (instanced && primcount == 0)) {
[email protected]6c788fb72010-08-26 02:16:316178 return error::kNoError;
6179 }
6180
[email protected]8eee29c2010-04-29 03:38:296181 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086182 Buffer* element_array_buffer =
6183 state_.vertex_attrib_manager->element_array_buffer();
6184
6185 if (!element_array_buffer->GetMaxValueForRange(
6186 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516187 LOCAL_SET_GL_ERROR(
6188 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296189 return error::kNoError;
6190 }
6191
[email protected]ad84a3a2012-06-08 21:42:436192 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206193 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516194 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206195 return error::kNoError;
6196 }
[email protected]c13e1da62011-09-09 21:48:306197 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436198 if (!SimulateAttrib0(
6199 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306200 return error::kNoError;
6201 }
[email protected]8fbedc02010-11-18 18:43:406202 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436203 if (SimulateFixedAttribs(
6204 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6205 primcount)) {
[email protected]8fbedc02010-11-18 18:43:406206 bool textures_set = SetBlackTextureForNonRenderableTextures();
[email protected]297ca1c2011-06-20 23:08:466207 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086208 // TODO(gman): Refactor to hide these details in BufferManager or
6209 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406210 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086211 bool used_client_side_array = false;
6212 if (element_array_buffer->IsClientSideArray()) {
6213 used_client_side_array = true;
6214 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6215 indices = element_array_buffer->GetRange(offset, 0);
6216 }
6217
[email protected]c6aef902012-02-14 03:31:426218 if (!instanced) {
6219 glDrawElements(mode, count, type, indices);
6220 } else {
6221 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6222 }
[email protected]17cfbe0e2013-03-07 01:26:086223
6224 if (used_client_side_array) {
6225 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6226 element_array_buffer->service_id());
6227 }
6228
[email protected]22e3f552012-03-13 01:54:196229 ProcessPendingQueries();
[email protected]8fbedc02010-11-18 18:43:406230 if (textures_set) {
6231 RestoreStateForNonRenderableTextures();
6232 }
6233 if (simulated_fixed_attribs) {
6234 RestoreStateForSimulatedFixedAttribs();
6235 }
[email protected]ba3176a2009-12-16 18:19:466236 }
[email protected]b1122982010-05-17 23:04:246237 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286238 RestoreStateForAttrib(0);
[email protected]b1122982010-05-17 23:04:246239 }
[email protected]96449d2c2009-11-25 00:01:326240 }
[email protected]f7a64ee2010-02-01 22:24:146241 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326242}
6243
[email protected]c6aef902012-02-14 03:31:426244error::Error GLES2DecoderImpl::HandleDrawElements(
[email protected]ed9f9cd2013-02-27 21:12:356245 uint32 immediate_data_size, const cmds::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:436246 return DoDrawElements("glDrawElements",
6247 false,
[email protected]c6aef902012-02-14 03:31:426248 static_cast<GLenum>(c.mode),
6249 static_cast<GLsizei>(c.count),
6250 static_cast<GLenum>(c.type),
6251 static_cast<int32>(c.index_offset),
6252 0);
6253}
6254
6255error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356256 uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156257 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516258 LOCAL_SET_GL_ERROR(
6259 GL_INVALID_OPERATION,
6260 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426261 return error::kNoError;
6262 }
[email protected]ad84a3a2012-06-08 21:42:436263 return DoDrawElements("glDrawElementsInstancedANGLE",
6264 true,
[email protected]c6aef902012-02-14 03:31:426265 static_cast<GLenum>(c.mode),
6266 static_cast<GLsizei>(c.count),
6267 static_cast<GLenum>(c.type),
6268 static_cast<int32>(c.index_offset),
6269 static_cast<GLsizei>(c.primcount));
6270}
6271
[email protected]269200b12010-11-18 22:53:066272GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236273 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6274 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076275 Buffer* buffer = GetBuffer(buffer_id);
6276 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036277 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516278 LOCAL_SET_GL_ERROR(
6279 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236280 } else {
[email protected]b10492f2013-03-08 05:24:076281 if (!buffer->GetMaxValueForRange(
6282 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036283 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516284 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066285 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436286 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236287 }
6288 }
6289 return max_vertex_accessed;
6290}
6291
[email protected]96449d2c2009-11-25 00:01:326292// Calls glShaderSource for the various versions of the ShaderSource command.
6293// Assumes that data / data_size points to a piece of memory that is in range
6294// of whatever context it came from (shared memory, immediate memory, bucket
6295// memory.)
[email protected]45bf5152010-02-12 00:11:316296error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036297 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576298 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426299 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6300 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316301 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326302 }
[email protected]45bf5152010-02-12 00:11:316303 // Note: We don't actually call glShaderSource here. We wait until
6304 // the call to glCompileShader.
[email protected]df37b9932013-03-08 05:21:426305 shader->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:146306 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326307}
6308
[email protected]f7a64ee2010-02-01 22:24:146309error::Error GLES2DecoderImpl::HandleShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356310 uint32 immediate_data_size, const cmds::ShaderSource& c) {
[email protected]96449d2c2009-11-25 00:01:326311 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316312 const char* data = GetSharedMemoryAs<const char*>(
[email protected]96449d2c2009-11-25 00:01:326313 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]ba3176a2009-12-16 18:19:466314 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146315 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326316 }
[email protected]ae51d192010-04-27 00:48:036317 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]96449d2c2009-11-25 00:01:326318}
6319
[email protected]f7a64ee2010-02-01 22:24:146320error::Error GLES2DecoderImpl::HandleShaderSourceImmediate(
[email protected]ed9f9cd2013-02-27 21:12:356321 uint32 immediate_data_size, const cmds::ShaderSourceImmediate& c) {
[email protected]96449d2c2009-11-25 00:01:326322 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316323 const char* data = GetImmediateDataAs<const char*>(
[email protected]07f54fcc2009-12-22 02:46:306324 c, data_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:466325 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146326 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326327 }
[email protected]ae51d192010-04-27 00:48:036328 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]45bf5152010-02-12 00:11:316329}
6330
[email protected]558847a2010-03-24 07:02:546331error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
[email protected]ed9f9cd2013-02-27 21:12:356332 uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:546333 Bucket* bucket = GetBucket(c.data_bucket_id);
6334 if (!bucket || bucket->size() == 0) {
6335 return error::kInvalidArguments;
6336 }
6337 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036338 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546339 bucket->size() - 1);
6340}
6341
[email protected]ae51d192010-04-27 00:48:036342void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386343 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426344 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6345 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316346 return;
6347 }
[email protected]f57bb282010-11-12 00:51:346348 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186349 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426350 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456351 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416352 }
[email protected]de17df392010-04-23 21:09:416353
[email protected]df37b9932013-03-08 05:21:426354 program_manager()->DoCompileShader(shader, translator, feature_info_);
[email protected]45bf5152010-02-12 00:11:316355};
6356
[email protected]ddd968b82010-03-02 00:44:296357void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426358 GLuint shader_id, GLenum pname, GLint* params) {
6359 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6360 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296361 return;
6362 }
[email protected]8f1ccdac2010-05-19 21:01:486363 switch (pname) {
6364 case GL_SHADER_SOURCE_LENGTH:
[email protected]df37b9932013-03-08 05:21:426365 *params = shader->source() ? shader->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:486366 return;
6367 case GL_COMPILE_STATUS:
[email protected]df37b9932013-03-08 05:21:426368 *params = compile_shader_always_succeeds_ ? true : shader->IsValid();
[email protected]e5186162010-06-14 18:54:416369 return;
[email protected]8f1ccdac2010-05-19 21:01:486370 case GL_INFO_LOG_LENGTH:
[email protected]df37b9932013-03-08 05:21:426371 *params = shader->log_info() ? shader->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:416372 return;
[email protected]d6a53e42011-10-05 00:09:366373 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]df37b9932013-03-08 05:21:426374 ForceCompileShaderIfPending(shader);
6375 *params = shader->translated_source() ?
6376 shader->translated_source()->size() + 1 : 0;
[email protected]d6a53e42011-10-05 00:09:366377 return;
[email protected]8f1ccdac2010-05-19 21:01:486378 default:
6379 break;
[email protected]ddd968b82010-03-02 00:44:296380 }
[email protected]df37b9932013-03-08 05:21:426381 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296382}
6383
[email protected]ae51d192010-04-27 00:48:036384error::Error GLES2DecoderImpl::HandleGetShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356385 uint32 immediate_data_size, const cmds::GetShaderSource& c) {
[email protected]df37b9932013-03-08 05:21:426386 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036387 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6388 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426389 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
6390 if (!shader || !shader->source()) {
[email protected]8eee29c2010-04-29 03:38:296391 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296392 return error::kNoError;
6393 }
[email protected]df37b9932013-03-08 05:21:426394 bucket->SetFromString(shader->source()->c_str());
[email protected]ae51d192010-04-27 00:48:036395 return error::kNoError;
6396}
6397
[email protected]d6a53e42011-10-05 00:09:366398error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6399 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:356400 const cmds::GetTranslatedShaderSourceANGLE& c) {
[email protected]df37b9932013-03-08 05:21:426401 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366402 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6403 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426404 Shader* shader = GetShaderInfoNotProgram(
6405 shader_id, "glTranslatedGetShaderSourceANGLE");
6406 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366407 bucket->SetSize(0);
6408 return error::kNoError;
6409 }
[email protected]df37b9932013-03-08 05:21:426410 ForceCompileShaderIfPending(shader);
[email protected]d6a53e42011-10-05 00:09:366411
[email protected]df37b9932013-03-08 05:21:426412 bucket->SetFromString(shader->translated_source() ?
6413 shader->translated_source()->c_str() : NULL);
[email protected]d6a53e42011-10-05 00:09:366414 return error::kNoError;
6415}
6416
[email protected]ae51d192010-04-27 00:48:036417error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356418 uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426419 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586420 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6421 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426422 Program* program = GetProgramInfoNotShader(
6423 program_id, "glGetProgramInfoLog");
6424 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466425 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036426 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316427 }
[email protected]df37b9932013-03-08 05:21:426428 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036429 return error::kNoError;
6430}
6431
6432error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356433 uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426434 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586435 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6436 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426437 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
6438 if (!shader || !shader->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466439 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036440 return error::kNoError;
6441 }
[email protected]df37b9932013-03-08 05:21:426442 bucket->SetFromString(shader->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036443 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326444}
6445
[email protected]d058bca2012-11-26 10:27:266446bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6447 return state_.GetEnabled(cap);
6448}
6449
[email protected]1958e0e2010-04-22 05:17:156450bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:216451 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106452 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156453}
6454
6455bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356456 const Framebuffer* framebuffer =
6457 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106458 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156459}
6460
6461bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366462 // IsProgram is true for programs as soon as they are created, until they are
6463 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:356464 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:106465 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156466}
6467
6468bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356469 const Renderbuffer* renderbuffer =
6470 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106471 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156472}
6473
6474bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366475 // IsShader is true for shaders as soon as they are created, until they
6476 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:356477 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:106478 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156479}
6480
6481bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356482 const Texture* texture = GetTexture(client_id);
[email protected]a0b78dc2011-11-11 10:43:106483 return texture && texture->IsValid() && !texture->IsDeleted();
[email protected]ae51d192010-04-27 00:48:036484}
6485
6486void GLES2DecoderImpl::DoAttachShader(
6487 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426488 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586489 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:426490 if (!program) {
[email protected]ae51d192010-04-27 00:48:036491 return;
[email protected]1958e0e2010-04-22 05:17:156492 }
[email protected]df37b9932013-03-08 05:21:426493 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
6494 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036495 return;
6496 }
[email protected]df37b9932013-03-08 05:21:426497 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516498 LOCAL_SET_GL_ERROR(
6499 GL_INVALID_OPERATION,
6500 "glAttachShader",
6501 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:316502 return;
6503 }
[email protected]df37b9932013-03-08 05:21:426504 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036505}
6506
6507void GLES2DecoderImpl::DoDetachShader(
6508 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426509 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586510 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:426511 if (!program) {
[email protected]ae51d192010-04-27 00:48:036512 return;
6513 }
[email protected]df37b9932013-03-08 05:21:426514 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
6515 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036516 return;
6517 }
[email protected]df37b9932013-03-08 05:21:426518 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516519 LOCAL_SET_GL_ERROR(
6520 GL_INVALID_OPERATION,
6521 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:226522 return;
6523 }
[email protected]df37b9932013-03-08 05:21:426524 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036525}
6526
6527void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:426528 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586529 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:426530 if (!program) {
[email protected]ae51d192010-04-27 00:48:036531 return;
6532 }
[email protected]df37b9932013-03-08 05:21:426533 program->Validate();
[email protected]1958e0e2010-04-22 05:17:156534}
6535
[email protected]ac77603c72013-03-08 13:52:066536void GLES2DecoderImpl::GetVertexAttribHelper(
6537 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:246538 switch (pname) {
6539 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:066540 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:246541 if (buffer && !buffer->IsDeleted()) {
6542 GLuint client_id;
6543 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6544 *params = client_id;
6545 }
6546 break;
6547 }
6548 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:066549 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:246550 break;
6551 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:066552 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:246553 break;
6554 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:066555 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:246556 break;
6557 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:066558 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:246559 break;
6560 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:066561 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:246562 break;
[email protected]c6aef902012-02-14 03:31:426563 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:066564 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:426565 break;
[email protected]ac77603c72013-03-08 13:52:066566 default:
6567 NOTREACHED();
6568 break;
6569 }
6570}
6571
6572void GLES2DecoderImpl::DoGetVertexAttribfv(
6573 GLuint index, GLenum pname, GLfloat* params) {
6574 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6575 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516576 LOCAL_SET_GL_ERROR(
6577 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066578 return;
6579 }
6580 switch (pname) {
6581 case GL_CURRENT_VERTEX_ATTRIB: {
6582 const Vec4& value = state_.attrib_values[index];
6583 params[0] = value.v[0];
6584 params[1] = value.v[1];
6585 params[2] = value.v[2];
6586 params[3] = value.v[3];
6587 break;
6588 }
6589 default: {
6590 GLint value = 0;
6591 GetVertexAttribHelper(attrib, pname, &value);
6592 *params = static_cast<GLfloat>(value);
6593 break;
6594 }
6595 }
6596}
6597
6598void GLES2DecoderImpl::DoGetVertexAttribiv(
6599 GLuint index, GLenum pname, GLint* params) {
6600 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6601 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516602 LOCAL_SET_GL_ERROR(
6603 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066604 return;
6605 }
6606 switch (pname) {
[email protected]af6380962012-11-29 23:24:136607 case GL_CURRENT_VERTEX_ATTRIB: {
6608 const Vec4& value = state_.attrib_values[index];
6609 params[0] = static_cast<GLint>(value.v[0]);
6610 params[1] = static_cast<GLint>(value.v[1]);
6611 params[2] = static_cast<GLint>(value.v[2]);
6612 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:246613 break;
[email protected]af6380962012-11-29 23:24:136614 }
[email protected]b1122982010-05-17 23:04:246615 default:
[email protected]ac77603c72013-03-08 13:52:066616 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:246617 break;
6618 }
6619}
6620
[email protected]af6380962012-11-29 23:24:136621bool GLES2DecoderImpl::SetVertexAttribValue(
6622 const char* function_name, GLuint index, const GLfloat* value) {
6623 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:516624 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:136625 return false;
[email protected]b1122982010-05-17 23:04:246626 }
[email protected]af6380962012-11-29 23:24:136627 Vec4& v = state_.attrib_values[index];
6628 v.v[0] = value[0];
6629 v.v[1] = value[1];
6630 v.v[2] = value[2];
6631 v.v[3] = value[3];
6632 return true;
6633}
6634
6635void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
6636 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
6637 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
6638 glVertexAttrib1f(index, v0);
6639 }
[email protected]b1122982010-05-17 23:04:246640}
6641
6642void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:136643 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
6644 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
6645 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:246646 }
[email protected]b1122982010-05-17 23:04:246647}
6648
6649void GLES2DecoderImpl::DoVertexAttrib3f(
6650 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:136651 GLfloat v[4] = { v0, v1, v2, 1.0f, };
6652 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
6653 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:246654 }
[email protected]b1122982010-05-17 23:04:246655}
6656
6657void GLES2DecoderImpl::DoVertexAttrib4f(
6658 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:136659 GLfloat v[4] = { v0, v1, v2, v3, };
6660 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
6661 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:246662 }
[email protected]b1122982010-05-17 23:04:246663}
6664
6665void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136666 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
6667 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
6668 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:246669 }
[email protected]b1122982010-05-17 23:04:246670}
6671
6672void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136673 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
6674 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
6675 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:246676 }
[email protected]b1122982010-05-17 23:04:246677}
6678
6679void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136680 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
6681 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
6682 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:246683 }
[email protected]b1122982010-05-17 23:04:246684}
6685
6686void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136687 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
6688 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:246689 }
[email protected]b1122982010-05-17 23:04:246690}
6691
[email protected]f7a64ee2010-02-01 22:24:146692error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]ed9f9cd2013-02-27 21:12:356693 uint32 immediate_data_size, const cmds::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:466694
[email protected]e259eb412012-10-13 05:47:246695 if (!state_.bound_array_buffer || state_.bound_array_buffer->IsDeleted()) {
6696 if (state_.vertex_attrib_manager == default_vertex_attrib_manager_) {
[email protected]ab09b612013-03-11 22:11:516697 LOCAL_SET_GL_ERROR(
6698 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:466699 return error::kNoError;
6700 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:516701 LOCAL_SET_GL_ERROR(
6702 GL_INVALID_VALUE,
6703 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:466704 return error::kNoError;
6705 }
[email protected]96449d2c2009-11-25 00:01:326706 }
[email protected]8eee29c2010-04-29 03:38:296707
6708 GLuint indx = c.indx;
6709 GLint size = c.size;
6710 GLenum type = c.type;
6711 GLboolean normalized = c.normalized;
6712 GLsizei stride = c.stride;
6713 GLsizei offset = c.offset;
6714 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:056715 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516716 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:296717 return error::kNoError;
6718 }
[email protected]9438b012010-06-15 22:55:056719 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:516720 LOCAL_SET_GL_ERROR(
6721 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:296722 return error::kNoError;
6723 }
6724 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516725 LOCAL_SET_GL_ERROR(
6726 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:296727 return error::kNoError;
6728 }
6729 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:516730 LOCAL_SET_GL_ERROR(
6731 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:296732 return error::kNoError;
6733 }
6734 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:516735 LOCAL_SET_GL_ERROR(
6736 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:296737 return error::kNoError;
6738 }
6739 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516740 LOCAL_SET_GL_ERROR(
6741 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296742 return error::kNoError;
6743 }
6744 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:316745 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]8eee29c2010-04-29 03:38:296746 if (offset % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:516747 LOCAL_SET_GL_ERROR(
6748 GL_INVALID_OPERATION,
6749 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:316750 return error::kNoError;
6751 }
6752 if (stride % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:516753 LOCAL_SET_GL_ERROR(
6754 GL_INVALID_OPERATION,
6755 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:296756 return error::kNoError;
6757 }
[email protected]e259eb412012-10-13 05:47:246758 state_.vertex_attrib_manager->SetAttribInfo(
[email protected]8fbedc02010-11-18 18:43:406759 indx,
[email protected]e259eb412012-10-13 05:47:246760 state_.bound_array_buffer,
[email protected]8eee29c2010-04-29 03:38:296761 size,
6762 type,
[email protected]b1122982010-05-17 23:04:246763 normalized,
6764 stride,
6765 stride != 0 ? stride : component_size * size,
[email protected]8eee29c2010-04-29 03:38:296766 offset);
[email protected]8fbedc02010-11-18 18:43:406767 if (type != GL_FIXED) {
6768 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
6769 }
[email protected]f7a64ee2010-02-01 22:24:146770 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326771}
6772
[email protected]43410e92012-04-20 17:06:286773void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
6774 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:246775 state_.viewport_x = x;
6776 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:026777 state_.viewport_width = std::min(width, viewport_max_width_);
6778 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:286779 glViewport(x, y, width, height);
6780}
6781
[email protected]c6aef902012-02-14 03:31:426782error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356783 uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156784 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516785 LOCAL_SET_GL_ERROR(
6786 GL_INVALID_OPERATION,
6787 "glVertexAttribDivisorANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426788 }
6789 GLuint index = c.index;
6790 GLuint divisor = c.divisor;
6791 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516792 LOCAL_SET_GL_ERROR(
6793 GL_INVALID_VALUE,
6794 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:426795 return error::kNoError;
6796 }
6797
[email protected]e259eb412012-10-13 05:47:246798 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:426799 index,
6800 divisor);
6801 glVertexAttribDivisorANGLE(index, divisor);
6802 return error::kNoError;
6803}
6804
[email protected]f7a64ee2010-02-01 22:24:146805error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]ed9f9cd2013-02-27 21:12:356806 uint32 immediate_data_size, const cmds::ReadPixels& c) {
[email protected]09e17272012-11-30 10:30:446807 if (ShouldDeferReads())
6808 return error::kDeferCommandUntilLater;
[email protected]612d2f82009-12-08 20:49:316809 GLint x = c.x;
6810 GLint y = c.y;
6811 GLsizei width = c.width;
6812 GLsizei height = c.height;
6813 GLenum format = c.format;
6814 GLenum type = c.type;
[email protected]57f223832010-03-19 01:57:566815 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:516816 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:566817 return error::kNoError;
6818 }
[email protected]ed9f9cd2013-02-27 21:12:356819 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:186820 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:346821 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246822 width, height, format, type, state_.pack_alignment, &pixels_size,
6823 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:186824 return error::kOutOfBounds;
6825 }
[email protected]612d2f82009-12-08 20:49:316826 void* pixels = GetSharedMemoryAs<void*>(
6827 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:106828 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:146829 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:466830 }
[email protected]de43f082013-04-02 01:16:106831 Result* result = NULL;
6832 if (c.result_shm_id != 0) {
6833 result = GetSharedMemoryAs<Result*>(
6834 c.result_shm_id, c.result_shm_offset, sizeof(*result));
6835 if (!result) {
6836 return error::kOutOfBounds;
6837 }
6838 }
[email protected]a51788e2010-02-24 21:54:256839
[email protected]9438b012010-06-15 22:55:056840 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:516841 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:296842 return error::kNoError;
6843 }
[email protected]9438b012010-06-15 22:55:056844 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516845 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:126846 return error::kNoError;
6847 }
[email protected]57f223832010-03-19 01:57:566848 if (width == 0 || height == 0) {
6849 return error::kNoError;
6850 }
6851
[email protected]57f223832010-03-19 01:57:566852 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:306853 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:566854
[email protected]3aad1a32012-09-07 20:54:476855 int32 max_x;
6856 int32 max_y;
6857 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:516858 LOCAL_SET_GL_ERROR(
6859 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:146860 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:316861 }
[email protected]57f223832010-03-19 01:57:566862
[email protected]0d6bfdc2011-11-02 01:32:206863 if (!CheckBoundFramebuffersValid("glReadPixels")) {
6864 return error::kNoError;
6865 }
6866
[email protected]ab09b612013-03-11 22:11:516867 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixel");
[email protected]a0b78dc2011-11-11 10:43:106868
6869 ScopedResolvedFrameBufferBinder binder(this, false, true);
6870
[email protected]d37231fa2010-04-09 21:16:026871 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:566872 // The user requested an out of range area. Get the results 1 line
6873 // at a time.
6874 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346875 uint32 unpadded_row_size;
6876 uint32 padded_row_size;
6877 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246878 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346879 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:516880 LOCAL_SET_GL_ERROR(
6881 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566882 return error::kNoError;
6883 }
6884
6885 GLint dest_x_offset = std::max(-x, 0);
6886 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:346887 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246888 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
6889 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:516890 LOCAL_SET_GL_ERROR(
6891 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566892 return error::kNoError;
6893 }
6894
6895 // Copy each row into the larger dest rect.
6896 int8* dst = static_cast<int8*>(pixels);
6897 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:026898 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:566899 GLint read_width = read_end_x - read_x;
6900 for (GLint yy = 0; yy < height; ++yy) {
6901 GLint ry = y + yy;
6902
6903 // Clear the row.
6904 memset(dst, 0, unpadded_row_size);
6905
6906 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:026907 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:566908 glReadPixels(
6909 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
6910 }
6911 dst += padded_row_size;
6912 }
6913 } else {
6914 glReadPixels(x, y, width, height, format, type, pixels);
6915 }
[email protected]ab09b612013-03-11 22:11:516916 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:256917 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:106918 if (result != NULL) {
6919 *result = true;
6920 }
[email protected]4848b9f82011-03-10 18:37:566921
6922 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
6923 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
[email protected]84eb4252012-06-29 22:56:446924 if ((channels_exist & 0x0008) == 0 &&
[email protected]62e155e2012-10-23 22:43:156925 workarounds().clear_alpha_in_readpixels) {
[email protected]4848b9f82011-03-10 18:37:566926 // Set the alpha to 255 because some drivers are buggy in this regard.
6927 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346928
6929 uint32 unpadded_row_size;
6930 uint32 padded_row_size;
6931 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246932 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346933 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:516934 LOCAL_SET_GL_ERROR(
6935 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]4848b9f82011-03-10 18:37:566936 return error::kNoError;
6937 }
6938 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time
6939 // of this implementation.
6940 if (type != GL_UNSIGNED_BYTE) {
[email protected]ab09b612013-03-11 22:11:516941 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436942 GL_INVALID_OPERATION, "glReadPixels",
6943 "unsupported readPixel format");
[email protected]4848b9f82011-03-10 18:37:566944 return error::kNoError;
6945 }
6946 switch (format) {
6947 case GL_RGBA:
[email protected]297ca1c2011-06-20 23:08:466948 case GL_BGRA_EXT:
[email protected]4848b9f82011-03-10 18:37:566949 case GL_ALPHA: {
6950 int offset = (format == GL_ALPHA) ? 0 : 3;
6951 int step = (format == GL_ALPHA) ? 1 : 4;
6952 uint8* dst = static_cast<uint8*>(pixels) + offset;
6953 for (GLint yy = 0; yy < height; ++yy) {
6954 uint8* end = dst + unpadded_row_size;
6955 for (uint8* d = dst; d < end; d += step) {
6956 *d = 255;
6957 }
6958 dst += padded_row_size;
6959 }
6960 break;
6961 }
6962 default:
6963 break;
6964 }
6965 }
[email protected]a51788e2010-02-24 21:54:256966 }
[email protected]4848b9f82011-03-10 18:37:566967
[email protected]f7a64ee2010-02-01 22:24:146968 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326969}
6970
[email protected]f7a64ee2010-02-01 22:24:146971error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]ed9f9cd2013-02-27 21:12:356972 uint32 immediate_data_size, const cmds::PixelStorei& c) {
[email protected]b9849abf2009-11-25 19:13:196973 GLenum pname = c.pname;
6974 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:056975 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:516976 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:126977 return error::kNoError;
6978 }
[email protected]222471d2011-11-30 18:06:396979 switch (pname) {
6980 case GL_PACK_ALIGNMENT:
6981 case GL_UNPACK_ALIGNMENT:
6982 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:516983 LOCAL_SET_GL_ERROR(
6984 GL_INVALID_VALUE, "glPixelStore", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:396985 return error::kNoError;
6986 }
[email protected]164d6d52012-05-05 00:55:036987 break;
[email protected]0a1e9ad2012-05-04 21:13:036988 case GL_UNPACK_FLIP_Y_CHROMIUM:
6989 unpack_flip_y_ = (param != 0);
6990 return error::kNoError;
6991 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
6992 unpack_premultiply_alpha_ = (param != 0);
6993 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:176994 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
6995 unpack_unpremultiply_alpha_ = (param != 0);
6996 return error::kNoError;
[email protected]222471d2011-11-30 18:06:396997 default:
6998 break;
[email protected]b9849abf2009-11-25 19:13:196999 }
7000 glPixelStorei(pname, param);
7001 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437002 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247003 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437004 break;
7005 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427006 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437007 break;
7008 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247009 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437010 break;
7011 default:
7012 // Validation should have prevented us from getting here.
7013 NOTREACHED();
7014 break;
[email protected]b9849abf2009-11-25 19:13:197015 }
[email protected]f7a64ee2010-02-01 22:24:147016 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197017}
7018
[email protected]1c75a3702011-11-11 14:15:287019error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:357020 uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:387021 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]6f5fac9d12012-06-26 21:02:457022 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) {
[email protected]ab09b612013-03-11 22:11:517023 LOCAL_SET_GL_ERROR(
7024 GL_INVALID_OPERATION,
7025 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:287026 return error::kNoError;
7027 }
[email protected]7794d512012-04-17 20:36:497028 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:287029 return error::kNoError;
[email protected]7794d512012-04-17 20:36:497030 } else {
7031 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:287032 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:497033 }
[email protected]1c75a3702011-11-11 14:15:287034}
7035
[email protected]558847a2010-03-24 07:02:547036error::Error GLES2DecoderImpl::GetAttribLocationHelper(
7037 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7038 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577039 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517040 LOCAL_SET_GL_ERROR(
7041 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577042 return error::kNoError;
7043 }
[email protected]df37b9932013-03-08 05:21:427044 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587045 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:427046 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147047 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197048 }
[email protected]df37b9932013-03-08 05:21:427049 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517050 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437051 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257052 return error::kNoError;
7053 }
[email protected]b9849abf2009-11-25 19:13:197054 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547055 location_shm_id, location_shm_offset, sizeof(GLint));
7056 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147057 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197058 }
[email protected]558847a2010-03-24 07:02:547059 // Require the client to init this incase the context is lost and we are no
7060 // longer executing commands.
7061 if (*location != -1) {
7062 return error::kGenericError;
7063 }
[email protected]df37b9932013-03-08 05:21:427064 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147065 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197066}
7067
[email protected]558847a2010-03-24 07:02:547068error::Error GLES2DecoderImpl::HandleGetAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:357069 uint32 immediate_data_size, const cmds::GetAttribLocation& c) {
[email protected]558847a2010-03-24 07:02:547070 uint32 name_size = c.data_size;
7071 const char* name = GetSharedMemoryAs<const char*>(
7072 c.name_shm_id, c.name_shm_offset, name_size);
7073 if (!name) {
7074 return error::kOutOfBounds;
7075 }
7076 String name_str(name, name_size);
7077 return GetAttribLocationHelper(
7078 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7079}
7080
[email protected]f7a64ee2010-02-01 22:24:147081error::Error GLES2DecoderImpl::HandleGetAttribLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357082 uint32 immediate_data_size, const cmds::GetAttribLocationImmediate& c) {
[email protected]558847a2010-03-24 07:02:547083 uint32 name_size = c.data_size;
7084 const char* name = GetImmediateDataAs<const char*>(
7085 c, name_size, immediate_data_size);
7086 if (!name) {
7087 return error::kOutOfBounds;
7088 }
7089 String name_str(name, name_size);
7090 return GetAttribLocationHelper(
7091 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7092}
7093
7094error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357095 uint32 immediate_data_size, const cmds::GetAttribLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547096 Bucket* bucket = GetBucket(c.name_bucket_id);
7097 if (!bucket) {
7098 return error::kInvalidArguments;
7099 }
7100 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187101 if (!bucket->GetAsString(&name_str)) {
7102 return error::kInvalidArguments;
7103 }
[email protected]558847a2010-03-24 07:02:547104 return GetAttribLocationHelper(
7105 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7106}
7107
7108error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7109 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7110 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577111 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517112 LOCAL_SET_GL_ERROR(
7113 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577114 return error::kNoError;
7115 }
[email protected]df37b9932013-03-08 05:21:427116 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587117 client_id, "glUniformLocation");
[email protected]df37b9932013-03-08 05:21:427118 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147119 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197120 }
[email protected]df37b9932013-03-08 05:21:427121 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517122 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437123 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257124 return error::kNoError;
7125 }
[email protected]b9849abf2009-11-25 19:13:197126 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547127 location_shm_id, location_shm_offset, sizeof(GLint));
7128 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147129 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197130 }
[email protected]558847a2010-03-24 07:02:547131 // Require the client to init this incase the context is lost an we are no
7132 // longer executing commands.
7133 if (*location != -1) {
7134 return error::kGenericError;
7135 }
[email protected]df37b9932013-03-08 05:21:427136 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147137 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197138}
7139
[email protected]f7a64ee2010-02-01 22:24:147140error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]ed9f9cd2013-02-27 21:12:357141 uint32 immediate_data_size, const cmds::GetUniformLocation& c) {
[email protected]b9849abf2009-11-25 19:13:197142 uint32 name_size = c.data_size;
7143 const char* name = GetSharedMemoryAs<const char*>(
7144 c.name_shm_id, c.name_shm_offset, name_size);
[email protected]558847a2010-03-24 07:02:547145 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147146 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197147 }
7148 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547149 return GetUniformLocationHelper(
7150 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197151}
7152
[email protected]f7a64ee2010-02-01 22:24:147153error::Error GLES2DecoderImpl::HandleGetUniformLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357154 uint32 immediate_data_size, const cmds::GetUniformLocationImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197155 uint32 name_size = c.data_size;
[email protected]07f54fcc2009-12-22 02:46:307156 const char* name = GetImmediateDataAs<const char*>(
7157 c, name_size, immediate_data_size);
[email protected]558847a2010-03-24 07:02:547158 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147159 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197160 }
7161 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547162 return GetUniformLocationHelper(
7163 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7164}
7165
7166error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357167 uint32 immediate_data_size, const cmds::GetUniformLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547168 Bucket* bucket = GetBucket(c.name_bucket_id);
7169 if (!bucket) {
7170 return error::kInvalidArguments;
7171 }
7172 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187173 if (!bucket->GetAsString(&name_str)) {
7174 return error::kInvalidArguments;
7175 }
[email protected]558847a2010-03-24 07:02:547176 return GetUniformLocationHelper(
7177 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197178}
7179
[email protected]ddd968b82010-03-02 00:44:297180error::Error GLES2DecoderImpl::HandleGetString(
[email protected]ed9f9cd2013-02-27 21:12:357181 uint32 immediate_data_size, const cmds::GetString& c) {
[email protected]ddd968b82010-03-02 00:44:297182 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057183 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517184 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297185 return error::kNoError;
7186 }
[email protected]1958e0e2010-04-22 05:17:157187 const char* gl_str = reinterpret_cast<const char*>(glGetString(name));
7188 const char* str = NULL;
[email protected]f0d74742011-10-03 16:31:047189 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157190 switch (name) {
7191 case GL_VERSION:
7192 str = "OpenGL ES 2.0 Chromium";
7193 break;
7194 case GL_SHADING_LANGUAGE_VERSION:
7195 str = "OpenGL ES GLSL ES 1.0 Chromium";
7196 break;
[email protected]32939602012-05-09 06:25:167197 case GL_RENDERER:
7198 str = "Chromium";
7199 break;
7200 case GL_VENDOR:
7201 str = "Chromium";
7202 break;
[email protected]1958e0e2010-04-22 05:17:157203 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047204 {
7205 // For WebGL contexts, strip out the OES derivatives extension if it has
7206 // not been enabled.
7207 if (force_webgl_glsl_validation_ &&
7208 !derivatives_explicitly_enabled_) {
7209 extensions = feature_info_->extensions();
7210 size_t offset = extensions.find(kOESDerivativeExtension);
7211 if (std::string::npos != offset) {
7212 extensions.replace(offset,
7213 offset + arraysize(kOESDerivativeExtension),
7214 std::string());
7215 }
[email protected]f0d74742011-10-03 16:31:047216 } else {
[email protected]6f5fac9d12012-06-26 21:02:457217 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047218 }
[email protected]6f5fac9d12012-06-26 21:02:457219 std::string surface_extensions = surface_->GetExtensions();
7220 if (!surface_extensions.empty())
7221 extensions += " " + surface_extensions;
7222 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047223 }
[email protected]1958e0e2010-04-22 05:17:157224 break;
7225 default:
7226 str = gl_str;
7227 break;
7228 }
[email protected]ddd968b82010-03-02 00:44:297229 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157230 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297231 return error::kNoError;
7232}
7233
[email protected]0c86dbf2010-03-05 08:14:117234void GLES2DecoderImpl::DoBufferData(
[email protected]b9363b22010-06-09 22:06:157235 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) {
[email protected]9438b012010-06-15 22:55:057236 if (!validators_->buffer_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517237 LOCAL_SET_GL_ERROR_INVALID_ENUM("glBufferData", target, "target");
[email protected]8eee29c2010-04-29 03:38:297238 return;
7239 }
[email protected]9438b012010-06-15 22:55:057240 if (!validators_->buffer_usage.IsValid(usage)) {
[email protected]ab09b612013-03-11 22:11:517241 LOCAL_SET_GL_ERROR_INVALID_ENUM("glBufferData", usage, "usage");
[email protected]0c86dbf2010-03-05 08:14:117242 return;
[email protected]3b6ec202010-03-05 05:16:237243 }
7244 if (size < 0) {
[email protected]ab09b612013-03-11 22:11:517245 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferData", "size < 0");
[email protected]037896bd2010-04-21 19:07:287246 return;
[email protected]3b6ec202010-03-05 05:16:237247 }
[email protected]17cfbe0e2013-03-07 01:26:087248 Buffer* buffer = GetBufferInfoForTarget(target);
7249 if (!buffer) {
[email protected]ab09b612013-03-11 22:11:517250 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:287251 return;
[email protected]3b6ec202010-03-05 05:16:237252 }
[email protected]7989c9e2013-01-23 06:39:267253
7254 if (!EnsureGPUMemoryAvailable(size)) {
[email protected]ab09b612013-03-11 22:11:517255 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glBufferData", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267256 return;
7257 }
7258
[email protected]d3eba342013-04-18 21:11:507259 buffer_manager()->DoBufferData(GetErrorState(), buffer, size, usage, data);
[email protected]0c86dbf2010-03-05 08:14:117260}
7261
7262error::Error GLES2DecoderImpl::HandleBufferData(
[email protected]ed9f9cd2013-02-27 21:12:357263 uint32 immediate_data_size, const cmds::BufferData& c) {
[email protected]0c86dbf2010-03-05 08:14:117264 GLenum target = static_cast<GLenum>(c.target);
7265 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7266 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7267 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7268 GLenum usage = static_cast<GLenum>(c.usage);
7269 const void* data = NULL;
7270 if (data_shm_id != 0 || data_shm_offset != 0) {
7271 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7272 if (!data) {
7273 return error::kOutOfBounds;
7274 }
7275 }
7276 DoBufferData(target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147277 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197278}
7279
[email protected]f7a64ee2010-02-01 22:24:147280error::Error GLES2DecoderImpl::HandleBufferDataImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357281 uint32 immediate_data_size, const cmds::BufferDataImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197282 GLenum target = static_cast<GLenum>(c.target);
7283 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
[email protected]07f54fcc2009-12-22 02:46:307284 const void* data = GetImmediateDataAs<const void*>(
7285 c, size, immediate_data_size);
7286 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147287 return error::kOutOfBounds;
[email protected]07f54fcc2009-12-22 02:46:307288 }
[email protected]b9849abf2009-11-25 19:13:197289 GLenum usage = static_cast<GLenum>(c.usage);
[email protected]0c86dbf2010-03-05 08:14:117290 DoBufferData(target, size, data, usage);
7291 return error::kNoError;
7292}
7293
7294void GLES2DecoderImpl::DoBufferSubData(
7295 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]17cfbe0e2013-03-07 01:26:087296 Buffer* buffer = GetBufferInfoForTarget(target);
7297 if (!buffer) {
[email protected]ab09b612013-03-11 22:11:517298 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:287299 return;
[email protected]a93bb842010-02-16 23:03:477300 }
[email protected]17cfbe0e2013-03-07 01:26:087301
[email protected]d3eba342013-04-18 21:11:507302 buffer_manager()->DoBufferSubData(GetErrorState(), buffer, offset, size,
7303 data);
[email protected]b9849abf2009-11-25 19:13:197304}
7305
[email protected]0d6bfdc2011-11-02 01:32:207306bool GLES2DecoderImpl::ClearLevel(
7307 unsigned service_id,
7308 unsigned bind_target,
7309 unsigned target,
7310 int level,
7311 unsigned format,
7312 unsigned type,
7313 int width,
[email protected]4502e6492011-12-14 19:39:157314 int height,
7315 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007316 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7317 if (IsAngle() && (channels & GLES2Util::kDepth) != 0) {
7318 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7319 // on depth formats.
7320 GLuint fb = 0;
7321 glGenFramebuffersEXT(1, &fb);
7322 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7323
7324 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7325 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7326 GL_DEPTH_ATTACHMENT;
7327
7328 glFramebufferTexture2DEXT(
7329 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7330 // ANGLE promises a depth only attachment ok.
7331 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7332 GL_FRAMEBUFFER_COMPLETE) {
7333 return false;
7334 }
7335 glClearStencil(0);
7336 glStencilMask(-1);
7337 glClearDepth(1.0f);
7338 glDepthMask(true);
7339 glDisable(GL_SCISSOR_TEST);
7340 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7341
7342 RestoreClearState();
7343
7344 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:357345 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:007346 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7347 GLuint fb_service_id =
7348 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7349 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7350 return true;
7351 }
7352
[email protected]45d15a62012-04-18 14:33:177353 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7354
7355 uint32 size;
7356 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:347357 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247358 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:177359 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:207360 return false;
7361 }
[email protected]45d15a62012-04-18 14:33:177362
[email protected]a5d3dad2012-05-26 04:34:447363 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7364
[email protected]45d15a62012-04-18 14:33:177365 int tile_height;
7366
7367 if (size > kMaxZeroSize) {
7368 if (kMaxZeroSize < padded_row_size) {
7369 // That'd be an awfully large texture.
7370 return false;
7371 }
7372 // We should never have a large total size with a zero row size.
7373 DCHECK_GT(padded_row_size, 0U);
7374 tile_height = kMaxZeroSize / padded_row_size;
7375 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247376 width, tile_height, format, type, state_.unpack_alignment, &size,
7377 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:177378 return false;
7379 }
[email protected]4502e6492011-12-14 19:39:157380 } else {
[email protected]45d15a62012-04-18 14:33:177381 tile_height = height;
7382 }
7383
7384 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:557385 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:177386 memset(zero.get(), 0, size);
7387 glBindTexture(bind_target, service_id);
7388
7389 GLint y = 0;
7390 while (y < height) {
7391 GLint h = y + tile_height > height ? height - y : tile_height;
7392 if (is_texture_immutable || h != height) {
7393 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7394 } else {
7395 WrappedTexImage2D(
7396 target, level, format, width, h, 0, format, type, zero.get());
7397 }
7398 y += tile_height;
[email protected]4502e6492011-12-14 19:39:157399 }
[email protected]02965c22013-03-09 02:40:077400 Texture* texture = GetTextureInfoForTarget(bind_target);
7401 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:207402 return true;
7403}
7404
[email protected]ad84a3a2012-06-08 21:42:437405namespace {
7406
7407const int kS3TCBlockWidth = 4;
7408const int kS3TCBlockHeight = 4;
7409const int kS3TCDXT1BlockSize = 8;
7410const int kS3TCDXT3AndDXT5BlockSize = 16;
[email protected]2d3765b2012-10-03 00:31:077411const int kETC1BlockWidth = 4;
7412const int kETC1BlockHeight = 4;
7413const int kETC1BlockSize = 8;
[email protected]ad84a3a2012-06-08 21:42:437414
7415bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:517416 return (size == 1) ||
7417 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:437418}
7419
7420} // anonymous namespace.
7421
7422bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7423 const char* function_name,
7424 GLsizei width, GLsizei height, GLenum format, size_t size) {
7425 unsigned int bytes_required = 0;
7426
7427 switch (format) {
7428 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7429 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: {
7430 int num_blocks_across =
7431 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7432 int num_blocks_down =
7433 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7434 int num_blocks = num_blocks_across * num_blocks_down;
7435 bytes_required = num_blocks * kS3TCDXT1BlockSize;
7436 break;
7437 }
7438 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7439 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7440 int num_blocks_across =
7441 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7442 int num_blocks_down =
7443 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7444 int num_blocks = num_blocks_across * num_blocks_down;
7445 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
7446 break;
7447 }
[email protected]2d3765b2012-10-03 00:31:077448 case GL_ETC1_RGB8_OES: {
7449 int num_blocks_across =
7450 (width + kETC1BlockWidth - 1) / kETC1BlockWidth;
7451 int num_blocks_down =
7452 (height + kETC1BlockHeight - 1) / kETC1BlockHeight;
7453 int num_blocks = num_blocks_across * num_blocks_down;
7454 bytes_required = num_blocks * kETC1BlockSize;
7455 break;
7456 }
[email protected]ad84a3a2012-06-08 21:42:437457 default:
[email protected]ab09b612013-03-11 22:11:517458 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:437459 return false;
7460 }
7461
7462 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:517463 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437464 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
7465 return false;
7466 }
7467
7468 return true;
7469}
7470
7471bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
7472 const char* function_name,
7473 GLint level, GLsizei width, GLsizei height, GLenum format) {
7474 switch (format) {
7475 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7476 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7477 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7478 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7479 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:517480 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437481 GL_INVALID_OPERATION, function_name,
7482 "width or height invalid for level");
7483 return false;
7484 }
7485 return true;
7486 }
[email protected]2d3765b2012-10-03 00:31:077487 case GL_ETC1_RGB8_OES:
7488 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:517489 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077490 GL_INVALID_OPERATION, function_name,
7491 "width or height invalid for level");
7492 return false;
7493 }
7494 return true;
[email protected]ad84a3a2012-06-08 21:42:437495 default:
7496 return false;
7497 }
7498}
7499
7500bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
7501 const char* function_name,
7502 GLenum target, GLint level, GLint xoffset, GLint yoffset,
7503 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:357504 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:437505 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:517506 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437507 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
7508 return false;
7509 }
7510
7511 switch (format) {
7512 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7513 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7514 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7515 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7516 const int kBlockWidth = 4;
7517 const int kBlockHeight = 4;
7518 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:517519 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437520 GL_INVALID_OPERATION, function_name,
7521 "xoffset or yoffset not multiple of 4");
7522 return false;
7523 }
7524 GLsizei tex_width = 0;
7525 GLsizei tex_height = 0;
7526 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
7527 width - xoffset > tex_width ||
7528 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:517529 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437530 GL_INVALID_OPERATION, function_name, "dimensions out of range");
7531 return false;
7532 }
7533 return ValidateCompressedTexDimensions(
7534 function_name, level, width, height, format);
7535 }
[email protected]2d3765b2012-10-03 00:31:077536 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:517537 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077538 GL_INVALID_OPERATION, function_name,
7539 "TexsubImage2d not supported for ECT1_RGB8_OES textures");
7540 return false;
7541 }
[email protected]ad84a3a2012-06-08 21:42:437542 default:
7543 return false;
7544 }
7545}
7546
[email protected]a93bb842010-02-16 23:03:477547error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
7548 GLenum target,
7549 GLint level,
7550 GLenum internal_format,
7551 GLsizei width,
7552 GLsizei height,
7553 GLint border,
7554 GLsizei image_size,
7555 const void* data) {
[email protected]a93bb842010-02-16 23:03:477556 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:057557 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517558 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7559 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297560 return error::kNoError;
7561 }
[email protected]9438b012010-06-15 22:55:057562 if (!validators_->compressed_texture_format.IsValid(
7563 internal_format)) {
[email protected]ab09b612013-03-11 22:11:517564 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:537565 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:477566 return error::kNoError;
7567 }
[email protected]80eb6b52012-01-19 00:14:417568 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477569 border != 0) {
[email protected]ab09b612013-03-11 22:11:517570 LOCAL_SET_GL_ERROR(
7571 GL_INVALID_VALUE,
7572 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:477573 return error::kNoError;
7574 }
[email protected]02965c22013-03-09 02:40:077575 Texture* texture = GetTextureInfoForTarget(target);
7576 if (!texture) {
[email protected]ab09b612013-03-11 22:11:517577 LOCAL_SET_GL_ERROR(
7578 GL_INVALID_VALUE,
7579 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:477580 return error::kNoError;
7581 }
[email protected]02965c22013-03-09 02:40:077582 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517583 LOCAL_SET_GL_ERROR(
7584 GL_INVALID_OPERATION,
7585 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:437586 return error::kNoError;
7587 }
7588
7589 if (!ValidateCompressedTexDimensions(
7590 "glCompressedTexImage2D", level, width, height, internal_format) ||
7591 !ValidateCompressedTexFuncData(
7592 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:177593 return error::kNoError;
7594 }
[email protected]968351b2011-12-20 08:26:517595
[email protected]7989c9e2013-01-23 06:39:267596 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:517597 LOCAL_SET_GL_ERROR(
7598 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267599 return error::kNoError;
7600 }
7601
[email protected]02965c22013-03-09 02:40:077602 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427603 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517604 // TODO(gman): If textures tracked which framebuffers they were attached to
7605 // we could just mark those framebuffers as not complete.
7606 framebuffer_manager()->IncFramebufferStateChangeCount();
7607 }
7608
[email protected]40d90a22013-04-09 03:39:557609 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:477610 if (!data) {
7611 zero.reset(new int8[image_size]);
7612 memset(zero.get(), 0, image_size);
7613 data = zero.get();
7614 }
[email protected]ab09b612013-03-11 22:11:517615 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:477616 glCompressedTexImage2D(
7617 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:517618 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:437619 if (error == GL_NO_ERROR) {
7620 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:077621 texture, target, level, internal_format, width, height, 1, border, 0, 0,
[email protected]0d6bfdc2011-11-02 01:32:207622 true);
[email protected]cadde4a2010-07-31 17:10:437623 }
[email protected]a93bb842010-02-16 23:03:477624 return error::kNoError;
7625}
7626
[email protected]f7a64ee2010-02-01 22:24:147627error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357628 uint32 immediate_data_size, const cmds::CompressedTexImage2D& c) {
[email protected]b9849abf2009-11-25 19:13:197629 GLenum target = static_cast<GLenum>(c.target);
7630 GLint level = static_cast<GLint>(c.level);
7631 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7632 GLsizei width = static_cast<GLsizei>(c.width);
7633 GLsizei height = static_cast<GLsizei>(c.height);
7634 GLint border = static_cast<GLint>(c.border);
7635 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
7636 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7637 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7638 const void* data = NULL;
7639 if (data_shm_id != 0 || data_shm_offset != 0) {
7640 data = GetSharedMemoryAs<const void*>(
7641 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:467642 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147643 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197644 }
7645 }
[email protected]a93bb842010-02-16 23:03:477646 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197647 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:197648}
7649
[email protected]f7a64ee2010-02-01 22:24:147650error::Error GLES2DecoderImpl::HandleCompressedTexImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357651 uint32 immediate_data_size, const cmds::CompressedTexImage2DImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197652 GLenum target = static_cast<GLenum>(c.target);
7653 GLint level = static_cast<GLint>(c.level);
7654 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7655 GLsizei width = static_cast<GLsizei>(c.width);
7656 GLsizei height = static_cast<GLsizei>(c.height);
7657 GLint border = static_cast<GLint>(c.border);
7658 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
[email protected]07f54fcc2009-12-22 02:46:307659 const void* data = GetImmediateDataAs<const void*>(
7660 c, image_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467661 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147662 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467663 }
[email protected]a93bb842010-02-16 23:03:477664 return DoCompressedTexImage2D(
7665 target, level, internal_format, width, height, border, image_size, data);
7666}
7667
[email protected]b6140d02010-05-17 14:47:167668error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
[email protected]ed9f9cd2013-02-27 21:12:357669 uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167670 GLenum target = static_cast<GLenum>(c.target);
7671 GLint level = static_cast<GLint>(c.level);
7672 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7673 GLsizei width = static_cast<GLsizei>(c.width);
7674 GLsizei height = static_cast<GLsizei>(c.height);
7675 GLint border = static_cast<GLint>(c.border);
7676 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287677 if (!bucket) {
7678 return error::kInvalidArguments;
7679 }
7680 uint32 data_size = bucket->size();
7681 GLsizei imageSize = data_size;
7682 const void* data = bucket->GetData(0, data_size);
7683 if (!data) {
7684 return error::kInvalidArguments;
7685 }
[email protected]b6140d02010-05-17 14:47:167686 return DoCompressedTexImage2D(
7687 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:287688 imageSize, data);
[email protected]b6140d02010-05-17 14:47:167689}
7690
7691error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
7692 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:357693 const cmds::CompressedTexSubImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167694 GLenum target = static_cast<GLenum>(c.target);
7695 GLint level = static_cast<GLint>(c.level);
7696 GLint xoffset = static_cast<GLint>(c.xoffset);
7697 GLint yoffset = static_cast<GLint>(c.yoffset);
7698 GLsizei width = static_cast<GLsizei>(c.width);
7699 GLsizei height = static_cast<GLsizei>(c.height);
7700 GLenum format = static_cast<GLenum>(c.format);
7701 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287702 if (!bucket) {
7703 return error::kInvalidArguments;
7704 }
[email protected]b6140d02010-05-17 14:47:167705 uint32 data_size = bucket->size();
7706 GLsizei imageSize = data_size;
7707 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:287708 if (!data) {
7709 return error::kInvalidArguments;
7710 }
[email protected]9438b012010-06-15 22:55:057711 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517712 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:537713 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:167714 return error::kNoError;
7715 }
[email protected]9438b012010-06-15 22:55:057716 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517717 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7718 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:057719 return error::kNoError;
7720 }
[email protected]b6140d02010-05-17 14:47:167721 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:517722 LOCAL_SET_GL_ERROR(
7723 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:167724 return error::kNoError;
7725 }
7726 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:517727 LOCAL_SET_GL_ERROR(
7728 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:167729 return error::kNoError;
7730 }
7731 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:517732 LOCAL_SET_GL_ERROR(
7733 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:167734 return error::kNoError;
7735 }
[email protected]cadde4a2010-07-31 17:10:437736 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:167737 target, level, xoffset, yoffset, width, height, format, imageSize, data);
7738 return error::kNoError;
7739}
7740
[email protected]81375742012-06-08 00:04:007741bool GLES2DecoderImpl::ValidateTextureParameters(
7742 const char* function_name,
7743 GLenum target, GLenum format, GLenum type, GLint level) {
7744 if (!feature_info_->GetTextureFormatValidator(format).IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517745 LOCAL_SET_GL_ERROR(
7746 GL_INVALID_OPERATION, function_name,
7747 (std::string("invalid type ") +
7748 GLES2Util::GetStringEnum(type) + " for format " +
7749 GLES2Util::GetStringEnum(format)).c_str());
[email protected]81375742012-06-08 00:04:007750 return false;
7751 }
7752
7753 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7754 if ((channels & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && level) {
[email protected]ab09b612013-03-11 22:11:517755 LOCAL_SET_GL_ERROR(
7756 GL_INVALID_OPERATION, function_name,
7757 (std::string("invalid type ") +
7758 GLES2Util::GetStringEnum(type) + " for format " +
7759 GLES2Util::GetStringEnum(format)).c_str());
[email protected]81375742012-06-08 00:04:007760 return false;
7761 }
7762 return true;
7763}
7764
[email protected]f598f422012-12-07 08:30:037765bool GLES2DecoderImpl::ValidateTexImage2D(
7766 const char* function_name,
7767 GLenum target,
7768 GLint level,
7769 GLenum internal_format,
7770 GLsizei width,
7771 GLsizei height,
7772 GLint border,
7773 GLenum format,
7774 GLenum type,
7775 const void* pixels,
7776 uint32 pixels_size) {
[email protected]9438b012010-06-15 22:55:057777 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517778 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:037779 return false;
[email protected]8eee29c2010-04-29 03:38:297780 }
[email protected]9438b012010-06-15 22:55:057781 if (!validators_->texture_format.IsValid(internal_format)) {
[email protected]ab09b612013-03-11 22:11:517782 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7783 function_name, internal_format, "internal_format");
[email protected]f598f422012-12-07 08:30:037784 return false;
[email protected]8eee29c2010-04-29 03:38:297785 }
[email protected]9438b012010-06-15 22:55:057786 if (!validators_->texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517787 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]f598f422012-12-07 08:30:037788 return false;
[email protected]8eee29c2010-04-29 03:38:297789 }
[email protected]9438b012010-06-15 22:55:057790 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517791 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]f598f422012-12-07 08:30:037792 return false;
[email protected]b9849abf2009-11-25 19:13:197793 }
[email protected]7b92c412010-07-20 17:48:257794 if (format != internal_format) {
[email protected]ab09b612013-03-11 22:11:517795 LOCAL_SET_GL_ERROR(
7796 GL_INVALID_OPERATION, function_name, "format != internalFormat");
[email protected]f598f422012-12-07 08:30:037797 return false;
[email protected]7b92c412010-07-20 17:48:257798 }
[email protected]f598f422012-12-07 08:30:037799 if (!ValidateTextureParameters(function_name, target, format, type, level)) {
7800 return false;
[email protected]81375742012-06-08 00:04:007801 }
[email protected]80eb6b52012-01-19 00:14:417802 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477803 border != 0) {
[email protected]ab09b612013-03-11 22:11:517804 LOCAL_SET_GL_ERROR(
7805 GL_INVALID_VALUE, function_name, "dimensions out of range");
[email protected]f598f422012-12-07 08:30:037806 return false;
[email protected]a93bb842010-02-16 23:03:477807 }
[email protected]81375742012-06-08 00:04:007808 if ((GLES2Util::GetChannelsForFormat(format) &
7809 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && pixels) {
[email protected]ab09b612013-03-11 22:11:517810 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:007811 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037812 function_name, "can not supply data for depth or stencil textures");
7813 return false;
[email protected]81375742012-06-08 00:04:007814 }
[email protected]02965c22013-03-09 02:40:077815 Texture* texture = GetTextureInfoForTarget(target);
7816 if (!texture) {
[email protected]ab09b612013-03-11 22:11:517817 LOCAL_SET_GL_ERROR(
7818 GL_INVALID_OPERATION, function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:037819 return false;
[email protected]a93bb842010-02-16 23:03:477820 }
[email protected]02965c22013-03-09 02:40:077821 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517822 LOCAL_SET_GL_ERROR(
7823 GL_INVALID_OPERATION, function_name, "texture is immutable");
[email protected]f598f422012-12-07 08:30:037824 return false;
[email protected]97dc7cbe2011-12-06 17:26:177825 }
[email protected]f598f422012-12-07 08:30:037826 return true;
7827}
[email protected]97dc7cbe2011-12-06 17:26:177828
[email protected]f598f422012-12-07 08:30:037829void GLES2DecoderImpl::DoTexImage2D(
7830 GLenum target,
7831 GLint level,
7832 GLenum internal_format,
7833 GLsizei width,
7834 GLsizei height,
7835 GLint border,
7836 GLenum format,
7837 GLenum type,
7838 const void* pixels,
7839 uint32 pixels_size) {
7840 if (!ValidateTexImage2D("glTexImage2D", target, level, internal_format,
7841 width, height, border, format, type, pixels, pixels_size)) {
7842 return;
7843 }
[email protected]7989c9e2013-01-23 06:39:267844
7845 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:517846 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267847 return;
7848 }
7849
[email protected]02965c22013-03-09 02:40:077850 Texture* texture = GetTextureInfoForTarget(target);
[email protected]0226c112011-07-22 03:25:077851 GLsizei tex_width = 0;
7852 GLsizei tex_height = 0;
7853 GLenum tex_type = 0;
7854 GLenum tex_format = 0;
7855 bool level_is_same =
[email protected]02965c22013-03-09 02:40:077856 texture->GetLevelSize(target, level, &tex_width, &tex_height) &&
7857 texture->GetLevelType(target, level, &tex_type, &tex_format) &&
[email protected]0226c112011-07-22 03:25:077858 width == tex_width && height == tex_height &&
7859 type == tex_type && format == tex_format;
7860
7861 if (level_is_same && !pixels) {
[email protected]02965c22013-03-09 02:40:077862 // Just set the level texture but mark the texture as uncleared.
[email protected]1bed6222011-12-21 11:21:397863 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:077864 texture,
[email protected]1bed6222011-12-21 11:21:397865 target, level, internal_format, width, height, 1, border, format, type,
7866 false);
[email protected]ea72ed222011-08-17 18:58:437867 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:037868 return;
[email protected]0226c112011-07-22 03:25:077869 }
7870
[email protected]02965c22013-03-09 02:40:077871 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427872 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517873 // TODO(gman): If textures tracked which framebuffers they were attached to
7874 // we could just mark those framebuffers as not complete.
7875 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]297ca1c2011-06-20 23:08:467876 }
7877
[email protected]1bed6222011-12-21 11:21:397878 if (!teximage2d_faster_than_texsubimage2d_ && level_is_same && pixels) {
[email protected]0226c112011-07-22 03:25:077879 glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels);
[email protected]02965c22013-03-09 02:40:077880 texture_manager()->SetLevelCleared(texture, target, level, true);
[email protected]0226c112011-07-22 03:25:077881 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:037882 return;
[email protected]7488d962010-07-16 02:41:587883 }
[email protected]876f6fee2010-08-02 23:10:327884
[email protected]ab09b612013-03-11 22:11:517885 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexImage2D");
[email protected]473c01ccb2011-06-07 01:33:307886 WrappedTexImage2D(
7887 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477888 pixels);
[email protected]ab09b612013-03-11 22:11:517889 GLenum error = LOCAL_PEEK_GL_ERROR("glTexImage2D");
[email protected]cadde4a2010-07-31 17:10:437890 if (error == GL_NO_ERROR) {
[email protected]0d6bfdc2011-11-02 01:32:207891 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:077892 texture,
[email protected]0d6bfdc2011-11-02 01:32:207893 target, level, internal_format, width, height, 1, border, format, type,
7894 pixels != NULL);
[email protected]b493ee622011-04-13 23:52:007895 tex_image_2d_failed_ = false;
[email protected]cadde4a2010-07-31 17:10:437896 }
[email protected]f598f422012-12-07 08:30:037897 return;
[email protected]b9849abf2009-11-25 19:13:197898}
7899
[email protected]f7a64ee2010-02-01 22:24:147900error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357901 uint32 immediate_data_size, const cmds::TexImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:387902 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
[email protected]b493ee622011-04-13 23:52:007903 tex_image_2d_failed_ = true;
[email protected]b9849abf2009-11-25 19:13:197904 GLenum target = static_cast<GLenum>(c.target);
7905 GLint level = static_cast<GLint>(c.level);
7906 GLint internal_format = static_cast<GLint>(c.internalformat);
7907 GLsizei width = static_cast<GLsizei>(c.width);
7908 GLsizei height = static_cast<GLsizei>(c.height);
7909 GLint border = static_cast<GLint>(c.border);
7910 GLenum format = static_cast<GLenum>(c.format);
7911 GLenum type = static_cast<GLenum>(c.type);
7912 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
7913 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:187914 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347915 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247916 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:347917 NULL)) {
[email protected]a76b0052010-03-05 00:33:187918 return error::kOutOfBounds;
7919 }
[email protected]b9849abf2009-11-25 19:13:197920 const void* pixels = NULL;
7921 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
7922 pixels = GetSharedMemoryAs<const void*>(
7923 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:467924 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147925 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197926 }
7927 }
[email protected]f598f422012-12-07 08:30:037928
7929 DoTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197930 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477931 pixels, pixels_size);
[email protected]f598f422012-12-07 08:30:037932 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197933}
7934
[email protected]f7a64ee2010-02-01 22:24:147935error::Error GLES2DecoderImpl::HandleTexImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357936 uint32 immediate_data_size, const cmds::TexImage2DImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197937 GLenum target = static_cast<GLenum>(c.target);
7938 GLint level = static_cast<GLint>(c.level);
[email protected]ba3176a2009-12-16 18:19:467939 GLint internal_format = static_cast<GLint>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:197940 GLsizei width = static_cast<GLsizei>(c.width);
7941 GLsizei height = static_cast<GLsizei>(c.height);
7942 GLint border = static_cast<GLint>(c.border);
7943 GLenum format = static_cast<GLenum>(c.format);
7944 GLenum type = static_cast<GLenum>(c.type);
[email protected]a76b0052010-03-05 00:33:187945 uint32 size;
[email protected]3458a64a2012-04-10 17:39:347946 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247947 width, height, format, type, state_.unpack_alignment, &size,
7948 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187949 return error::kOutOfBounds;
7950 }
[email protected]07f54fcc2009-12-22 02:46:307951 const void* pixels = GetImmediateDataAs<const void*>(
7952 c, size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467953 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147954 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467955 }
[email protected]a93bb842010-02-16 23:03:477956 DoTexImage2D(
[email protected]ba3176a2009-12-16 18:19:467957 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477958 pixels, size);
[email protected]f7a64ee2010-02-01 22:24:147959 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327960}
7961
[email protected]cadde4a2010-07-31 17:10:437962void GLES2DecoderImpl::DoCompressedTexSubImage2D(
7963 GLenum target,
7964 GLint level,
7965 GLint xoffset,
7966 GLint yoffset,
7967 GLsizei width,
7968 GLsizei height,
7969 GLenum format,
7970 GLsizei image_size,
7971 const void * data) {
[email protected]02965c22013-03-09 02:40:077972 Texture* texture = GetTextureInfoForTarget(target);
7973 if (!texture) {
[email protected]ab09b612013-03-11 22:11:517974 LOCAL_SET_GL_ERROR(
7975 GL_INVALID_OPERATION,
7976 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437977 return;
7978 }
7979 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:527980 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:077981 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:517982 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:527983 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437984 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:527985 return;
7986 }
7987 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:517988 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:527989 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437990 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:527991 return;
7992 }
[email protected]02965c22013-03-09 02:40:077993 if (!texture->ValidForTexture(
[email protected]df6cf1ad2011-01-29 01:20:527994 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:517995 LOCAL_SET_GL_ERROR(
7996 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437997 return;
7998 }
[email protected]ad84a3a2012-06-08 21:42:437999
8000 if (!ValidateCompressedTexFuncData(
8001 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8002 !ValidateCompressedTexSubDimensions(
8003 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:078004 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:438005 return;
8006 }
8007
8008
[email protected]0d6bfdc2011-11-02 01:32:208009 // Note: There is no need to deal with texture cleared tracking here
8010 // because the validation above means you can only get here if the level
8011 // is already a matching compressed format and in that case
8012 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:438013 glCompressedTexSubImage2D(
8014 target, level, xoffset, yoffset, width, height, format, image_size, data);
8015}
8016
[email protected]6e288612010-12-21 20:45:038017static void Clip(
8018 GLint start, GLint range, GLint sourceRange,
8019 GLint* out_start, GLint* out_range) {
8020 DCHECK(out_start);
8021 DCHECK(out_range);
8022 if (start < 0) {
8023 range += start;
8024 start = 0;
8025 }
8026 GLint end = start + range;
8027 if (end > sourceRange) {
8028 range -= end - sourceRange;
8029 }
8030 *out_start = start;
8031 *out_range = range;
8032}
8033
[email protected]cadde4a2010-07-31 17:10:438034void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:448035 GLenum target,
8036 GLint level,
8037 GLenum internal_format,
8038 GLint x,
8039 GLint y,
8040 GLsizei width,
8041 GLsizei height,
8042 GLint border) {
[email protected]09e17272012-11-30 10:30:448043 DCHECK(!ShouldDeferReads());
[email protected]02965c22013-03-09 02:40:078044 Texture* texture = GetTextureInfoForTarget(target);
8045 if (!texture) {
[email protected]ab09b612013-03-11 22:11:518046 LOCAL_SET_GL_ERROR(
8047 GL_INVALID_OPERATION,
8048 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438049 return;
8050 }
[email protected]02965c22013-03-09 02:40:078051 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518052 LOCAL_SET_GL_ERROR(
8053 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:178054 }
[email protected]80eb6b52012-01-19 00:14:418055 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:188056 border != 0) {
[email protected]ab09b612013-03-11 22:11:518057 LOCAL_SET_GL_ERROR(
8058 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188059 return;
8060 }
[email protected]81375742012-06-08 00:04:008061 if (!ValidateTextureParameters(
8062 "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) {
8063 return;
8064 }
[email protected]f5719fb2010-08-04 18:27:188065
[email protected]9edc6b22010-12-23 02:00:268066 // Check we have compatible formats.
8067 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8068 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8069 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8070
8071 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518072 LOCAL_SET_GL_ERROR(
8073 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268074 return;
8075 }
8076
[email protected]81375742012-06-08 00:04:008077 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518078 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008079 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268080 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8081 return;
8082 }
8083
8084 uint32 estimated_size = 0;
8085 if (!GLES2Util::ComputeImageDataSizes(
8086 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8087 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518088 LOCAL_SET_GL_ERROR(
8089 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268090 return;
8091 }
8092
8093 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518094 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008095 return;
8096 }
8097
[email protected]a0b78dc2011-11-11 10:43:108098 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8099 return;
8100 }
8101
[email protected]ab09b612013-03-11 22:11:518102 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278103 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038104 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268105
[email protected]02965c22013-03-09 02:40:078106 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:428107 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:518108 // TODO(gman): If textures tracked which framebuffers they were attached to
8109 // we could just mark those framebuffers as not complete.
8110 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]297ca1c2011-06-20 23:08:468111 }
8112
[email protected]9edc6b22010-12-23 02:00:268113 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038114 GLint copyX = 0;
8115 GLint copyY = 0;
8116 GLint copyWidth = 0;
8117 GLint copyHeight = 0;
8118 Clip(x, width, size.width(), &copyX, &copyWidth);
8119 Clip(y, height, size.height(), &copyY, &copyHeight);
8120
8121 if (copyX != x ||
8122 copyY != y ||
8123 copyWidth != width ||
8124 copyHeight != height) {
8125 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208126 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078127 texture->service_id(), texture->target(),
[email protected]4502e6492011-12-14 19:39:158128 target, level, internal_format, GL_UNSIGNED_BYTE, width, height,
[email protected]02965c22013-03-09 02:40:078129 texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518130 LOCAL_SET_GL_ERROR(
8131 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038132 return;
8133 }
[email protected]6e288612010-12-21 20:45:038134 if (copyHeight > 0 && copyWidth > 0) {
8135 GLint dx = copyX - x;
8136 GLint dy = copyY - y;
8137 GLint destX = dx;
8138 GLint destY = dy;
8139 glCopyTexSubImage2D(target, level,
8140 destX, destY, copyX, copyY,
8141 copyWidth, copyHeight);
8142 }
8143 } else {
8144 glCopyTexImage2D(target, level, internal_format,
8145 copyX, copyY, copyWidth, copyHeight, border);
8146 }
[email protected]ab09b612013-03-11 22:11:518147 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438148 if (error == GL_NO_ERROR) {
8149 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:078150 texture, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208151 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438152 }
8153}
8154
8155void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448156 GLenum target,
8157 GLint level,
8158 GLint xoffset,
8159 GLint yoffset,
8160 GLint x,
8161 GLint y,
8162 GLsizei width,
8163 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448164 DCHECK(!ShouldDeferReads());
[email protected]02965c22013-03-09 02:40:078165 Texture* texture = GetTextureInfoForTarget(target);
8166 if (!texture) {
[email protected]ab09b612013-03-11 22:11:518167 LOCAL_SET_GL_ERROR(
8168 GL_INVALID_OPERATION,
8169 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438170 return;
8171 }
8172 GLenum type = 0;
8173 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078174 if (!texture->GetLevelType(target, level, &type, &format) ||
8175 !texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438176 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518177 LOCAL_SET_GL_ERROR(
8178 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438179 return;
8180 }
[email protected]02965c22013-03-09 02:40:078181 if (texture->AsyncTransferIsInProgress()) {
[email protected]ab09b612013-03-11 22:11:518182 LOCAL_SET_GL_ERROR(
8183 GL_INVALID_OPERATION,
8184 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598185 return;
8186 }
[email protected]9edc6b22010-12-23 02:00:268187
8188 // Check we have compatible formats.
8189 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8190 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8191 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8192
[email protected]2d3765b2012-10-03 00:31:078193 if (!channels_needed ||
8194 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518195 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438196 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268197 return;
8198 }
8199
[email protected]81375742012-06-08 00:04:008200 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518201 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008202 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438203 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008204 return;
8205 }
8206
[email protected]a0b78dc2011-11-11 10:43:108207 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8208 return;
8209 }
8210
[email protected]de26b3c2011-08-03 21:54:278211 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038212 gfx::Size size = GetBoundReadFrameBufferSize();
8213 GLint copyX = 0;
8214 GLint copyY = 0;
8215 GLint copyWidth = 0;
8216 GLint copyHeight = 0;
8217 Clip(x, width, size.width(), &copyX, &copyWidth);
8218 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208219
[email protected]02965c22013-03-09 02:40:078220 if (!texture_manager()->ClearTextureLevel(this, texture, target, level)) {
[email protected]ab09b612013-03-11 22:11:518221 LOCAL_SET_GL_ERROR(
8222 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208223 return;
8224 }
8225
[email protected]6e288612010-12-21 20:45:038226 if (copyX != x ||
8227 copyY != y ||
8228 copyWidth != width ||
8229 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208230 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038231 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348232 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248233 width, height, format, type, state_.unpack_alignment, &pixels_size,
8234 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518235 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438236 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038237 return;
8238 }
[email protected]40d90a22013-04-09 03:39:558239 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038240 memset(zero.get(), 0, pixels_size);
8241 glTexSubImage2D(
8242 target, level, xoffset, yoffset, width, height,
8243 format, type, zero.get());
8244 }
[email protected]0d6bfdc2011-11-02 01:32:208245
[email protected]6e288612010-12-21 20:45:038246 if (copyHeight > 0 && copyWidth > 0) {
8247 GLint dx = copyX - x;
8248 GLint dy = copyY - y;
8249 GLint destX = xoffset + dx;
8250 GLint destY = yoffset + dy;
8251 glCopyTexSubImage2D(target, level,
8252 destX, destY, copyX, copyY,
8253 copyWidth, copyHeight);
8254 }
[email protected]cadde4a2010-07-31 17:10:438255}
8256
[email protected]f598f422012-12-07 08:30:038257bool GLES2DecoderImpl::ValidateTexSubImage2D(
8258 error::Error* error,
8259 const char* function_name,
8260 GLenum target,
8261 GLint level,
8262 GLint xoffset,
8263 GLint yoffset,
8264 GLsizei width,
8265 GLsizei height,
8266 GLenum format,
8267 GLenum type,
8268 const void * data) {
8269 (*error) = error::kNoError;
8270 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518271 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038272 return false;
8273 }
8274 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518275 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038276 return false;
8277 }
8278 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518279 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038280 return false;
8281 }
8282 if (!validators_->texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518283 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]f598f422012-12-07 08:30:038284 return false;
8285 }
8286 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:518287 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]f598f422012-12-07 08:30:038288 return false;
8289 }
[email protected]02965c22013-03-09 02:40:078290 Texture* texture = GetTextureInfoForTarget(target);
8291 if (!texture) {
[email protected]ab09b612013-03-11 22:11:518292 LOCAL_SET_GL_ERROR(
8293 GL_INVALID_OPERATION,
8294 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038295 return false;
[email protected]cadde4a2010-07-31 17:10:438296 }
[email protected]df6cf1ad2011-01-29 01:20:528297 GLenum current_type = 0;
8298 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078299 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518300 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038301 GL_INVALID_OPERATION, function_name, "level does not exist.");
8302 return false;
[email protected]df6cf1ad2011-01-29 01:20:528303 }
8304 if (format != internal_format) {
[email protected]ab09b612013-03-11 22:11:518305 LOCAL_SET_GL_ERROR(
8306 GL_INVALID_OPERATION,
8307 function_name, "format does not match internal format.");
[email protected]f598f422012-12-07 08:30:038308 return false;
[email protected]df6cf1ad2011-01-29 01:20:528309 }
8310 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518311 LOCAL_SET_GL_ERROR(
8312 GL_INVALID_OPERATION,
8313 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038314 return false;
[email protected]df6cf1ad2011-01-29 01:20:528315 }
[email protected]02965c22013-03-09 02:40:078316 if (texture->AsyncTransferIsInProgress()) {
[email protected]ab09b612013-03-11 22:11:518317 LOCAL_SET_GL_ERROR(
8318 GL_INVALID_OPERATION,
8319 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598320 return false;
8321 }
[email protected]02965c22013-03-09 02:40:078322 if (!texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438323 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518324 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038325 return false;
[email protected]cadde4a2010-07-31 17:10:438326 }
[email protected]81375742012-06-08 00:04:008327 if ((GLES2Util::GetChannelsForFormat(format) &
8328 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518329 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008330 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038331 function_name, "can not supply data for depth or stencil textures");
8332 return false;
[email protected]81375742012-06-08 00:04:008333 }
[email protected]f598f422012-12-07 08:30:038334 if (data == NULL) {
8335 (*error) = error::kOutOfBounds;
8336 return false;
8337 }
8338 return true;
8339}
[email protected]81375742012-06-08 00:04:008340
[email protected]f598f422012-12-07 08:30:038341error::Error GLES2DecoderImpl::DoTexSubImage2D(
8342 GLenum target,
8343 GLint level,
8344 GLint xoffset,
8345 GLint yoffset,
8346 GLsizei width,
8347 GLsizei height,
8348 GLenum format,
8349 GLenum type,
8350 const void * data) {
8351 error::Error error = error::kNoError;
8352 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8353 xoffset, yoffset, width, height, format, type, data)) {
8354 return error;
8355 }
[email protected]02965c22013-03-09 02:40:078356 Texture* texture = GetTextureInfoForTarget(target);
[email protected]4502e6492011-12-14 19:39:158357 GLsizei tex_width = 0;
8358 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078359 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:158360 DCHECK(ok);
8361 if (xoffset != 0 || yoffset != 0 ||
8362 width != tex_width || height != tex_height) {
[email protected]02965c22013-03-09 02:40:078363 if (!texture_manager()->ClearTextureLevel(this, texture, target, level)) {
[email protected]ab09b612013-03-11 22:11:518364 LOCAL_SET_GL_ERROR(
8365 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038366 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308367 }
[email protected]63b465922012-09-06 02:04:528368 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158369 glTexSubImage2D(
8370 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038371 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208372 }
[email protected]4502e6492011-12-14 19:39:158373
[email protected]02965c22013-03-09 02:40:078374 if (teximage2d_faster_than_texsubimage2d_ && !texture->IsImmutable()) {
[email protected]63b465922012-09-06 02:04:528375 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158376 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
8377 // same as internal_foramt. If that changes we'll need to look them up.
8378 WrappedTexImage2D(
8379 target, level, format, width, height, 0, format, type, data);
8380 } else {
[email protected]63b465922012-09-06 02:04:528381 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158382 glTexSubImage2D(
8383 target, level, xoffset, yoffset, width, height, format, type, data);
8384 }
[email protected]02965c22013-03-09 02:40:078385 texture_manager()->SetLevelCleared(texture, target, level, true);
[email protected]f598f422012-12-07 08:30:038386 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438387}
8388
[email protected]b493ee622011-04-13 23:52:008389error::Error GLES2DecoderImpl::HandleTexSubImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358390 uint32 immediate_data_size, const cmds::TexSubImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388391 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
[email protected]b493ee622011-04-13 23:52:008392 GLboolean internal = static_cast<GLboolean>(c.internal);
8393 if (internal == GL_TRUE && tex_image_2d_failed_)
8394 return error::kNoError;
8395
8396 GLenum target = static_cast<GLenum>(c.target);
8397 GLint level = static_cast<GLint>(c.level);
8398 GLint xoffset = static_cast<GLint>(c.xoffset);
8399 GLint yoffset = static_cast<GLint>(c.yoffset);
8400 GLsizei width = static_cast<GLsizei>(c.width);
8401 GLsizei height = static_cast<GLsizei>(c.height);
8402 GLenum format = static_cast<GLenum>(c.format);
8403 GLenum type = static_cast<GLenum>(c.type);
8404 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348405 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248406 width, height, format, type, state_.unpack_alignment, &data_size,
8407 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008408 return error::kOutOfBounds;
8409 }
8410 const void* pixels = GetSharedMemoryAs<const void*>(
8411 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038412 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008413 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008414}
8415
8416error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:358417 uint32 immediate_data_size, const cmds::TexSubImage2DImmediate& c) {
[email protected]b493ee622011-04-13 23:52:008418 GLboolean internal = static_cast<GLboolean>(c.internal);
8419 if (internal == GL_TRUE && tex_image_2d_failed_)
8420 return error::kNoError;
8421
8422 GLenum target = static_cast<GLenum>(c.target);
8423 GLint level = static_cast<GLint>(c.level);
8424 GLint xoffset = static_cast<GLint>(c.xoffset);
8425 GLint yoffset = static_cast<GLint>(c.yoffset);
8426 GLsizei width = static_cast<GLsizei>(c.width);
8427 GLsizei height = static_cast<GLsizei>(c.height);
8428 GLenum format = static_cast<GLenum>(c.format);
8429 GLenum type = static_cast<GLenum>(c.type);
8430 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348431 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248432 width, height, format, type, state_.unpack_alignment, &data_size,
8433 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008434 return error::kOutOfBounds;
8435 }
8436 const void* pixels = GetImmediateDataAs<const void*>(
8437 c, data_size, immediate_data_size);
[email protected]f598f422012-12-07 08:30:038438 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008439 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008440}
8441
[email protected]f7a64ee2010-02-01 22:24:148442error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]ed9f9cd2013-02-27 21:12:358443 uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:368444 GLuint index = static_cast<GLuint>(c.index);
8445 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:358446 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:258447 Result* result = GetSharedMemoryAs<Result*>(
8448 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:368449 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:148450 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:368451 }
[email protected]07d0cc82010-02-17 04:51:408452 // Check that the client initialized the result.
8453 if (result->size != 0) {
8454 return error::kInvalidArguments;
8455 }
[email protected]9438b012010-06-15 22:55:058456 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:518457 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8458 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:148459 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368460 }
[email protected]3916c97e2010-02-25 03:20:508461 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:518462 LOCAL_SET_GL_ERROR(
8463 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:148464 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368465 }
[email protected]0bfd9882010-02-05 23:02:258466 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:088467 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:358468 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:148469 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328470}
8471
[email protected]f7b85372010-02-03 01:11:378472bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:428473 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:378474 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:128475 error::Error* error, GLint* real_location,
8476 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:108477 DCHECK(error);
8478 DCHECK(service_id);
8479 DCHECK(result_pointer);
8480 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:128481 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:378482 *error = error::kNoError;
8483 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:258484 SizedResult<GLint>* result;
8485 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8486 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8487 if (!result) {
[email protected]f7b85372010-02-03 01:11:378488 *error = error::kOutOfBounds;
8489 return false;
8490 }
[email protected]0bfd9882010-02-05 23:02:258491 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:378492 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:258493 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:428494 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
8495 if (!program) {
[email protected]ae51d192010-04-27 00:48:038496 return false;
8497 }
[email protected]df37b9932013-03-08 05:21:428498 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:378499 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:518500 LOCAL_SET_GL_ERROR(
8501 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:378502 return false;
8503 }
[email protected]df37b9932013-03-08 05:21:428504 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:368505 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:358506 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428507 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:128508 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:368509 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:378510 // No such location.
[email protected]ab09b612013-03-11 22:11:518511 LOCAL_SET_GL_ERROR(
8512 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:378513 return false;
8514 }
[email protected]43c2f1f2011-03-25 18:35:368515 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:508516 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:378517 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:518518 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:378519 return false;
8520 }
[email protected]0bfd9882010-02-05 23:02:258521 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8522 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8523 if (!result) {
[email protected]f7b85372010-02-03 01:11:378524 *error = error::kOutOfBounds;
8525 return false;
8526 }
[email protected]0bfd9882010-02-05 23:02:258527 result->size = size;
[email protected]939e7362010-05-13 20:49:108528 *result_type = type;
[email protected]f7b85372010-02-03 01:11:378529 return true;
8530}
8531
[email protected]f7a64ee2010-02-01 22:24:148532error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]ed9f9cd2013-02-27 21:12:358533 uint32 immediate_data_size, const cmds::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:378534 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338535 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378536 GLuint service_id;
[email protected]939e7362010-05-13 20:49:108537 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:128538 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378539 Error error;
[email protected]0bfd9882010-02-05 23:02:258540 void* result;
[email protected]f7b85372010-02-03 01:11:378541 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128542 program, fake_location, c.params_shm_id, c.params_shm_offset,
8543 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:258544 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:128545 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:358546 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:378547 }
8548 return error;
[email protected]96449d2c2009-11-25 00:01:328549}
8550
[email protected]f7a64ee2010-02-01 22:24:148551error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]ed9f9cd2013-02-27 21:12:358552 uint32 immediate_data_size, const cmds::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:378553 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338554 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378555 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:128556 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378557 Error error;
[email protected]ed9f9cd2013-02-27 21:12:358558 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:108559 Result* result;
8560 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:378561 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128562 program, fake_location, c.params_shm_id, c.params_shm_offset,
8563 &error, &real_location, &service_id,
8564 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:108565 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8566 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8567 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:558568 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:128569 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:108570 GLfloat* dst = result->GetData();
8571 for (GLsizei ii = 0; ii < num_values; ++ii) {
8572 dst[ii] = (temp[ii] != 0);
8573 }
8574 } else {
[email protected]1b0a6752012-02-22 03:44:128575 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:108576 }
[email protected]f7b85372010-02-03 01:11:378577 }
8578 return error;
[email protected]96449d2c2009-11-25 00:01:328579}
8580
[email protected]f7a64ee2010-02-01 22:24:148581error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]ed9f9cd2013-02-27 21:12:358582 uint32 immediate_data_size, const cmds::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:258583 GLenum shader_type = static_cast<GLenum>(c.shadertype);
8584 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:358585 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:258586 Result* result = GetSharedMemoryAs<Result*>(
8587 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8588 if (!result) {
8589 return error::kOutOfBounds;
8590 }
[email protected]07d0cc82010-02-17 04:51:408591 // Check that the client initialized the result.
8592 if (result->success != 0) {
8593 return error::kInvalidArguments;
8594 }
[email protected]9438b012010-06-15 22:55:058595 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:518596 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538597 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:298598 return error::kNoError;
8599 }
[email protected]9438b012010-06-15 22:55:058600 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:518601 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538602 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:298603 return error::kNoError;
8604 }
8605
8606 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:408607
8608 GLint range[2] = {0, 0};
8609 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:218610 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:408611
8612 result->min_range = range[0];
8613 result->max_range = range[1];
8614 result->precision = precision;
8615
[email protected]f7a64ee2010-02-01 22:24:148616 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328617}
8618
[email protected]f7a64ee2010-02-01 22:24:148619error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]ed9f9cd2013-02-27 21:12:358620 uint32 immediate_data_size, const cmds::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:258621 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:428622 GLuint program_id = static_cast<GLuint>(c.program);
8623 Program* program = GetProgramInfoNotShader(
8624 program_id, "glGetAttachedShaders");
8625 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258626 return error::kNoError;
8627 }
[email protected]ed9f9cd2013-02-27 21:12:358628 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:258629 uint32 max_count = Result::ComputeMaxResults(result_size);
8630 Result* result = GetSharedMemoryAs<Result*>(
8631 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8632 if (!result) {
8633 return error::kOutOfBounds;
8634 }
[email protected]07d0cc82010-02-17 04:51:408635 // Check that the client initialized the result.
8636 if (result->size != 0) {
8637 return error::kInvalidArguments;
8638 }
[email protected]0bfd9882010-02-05 23:02:258639 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:038640 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:428641 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:258642 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:038643 if (!shader_manager()->GetClientId(result->GetData()[ii],
8644 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:258645 NOTREACHED();
8646 return error::kGenericError;
8647 }
8648 }
8649 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:148650 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328651}
8652
[email protected]f7a64ee2010-02-01 22:24:148653error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]ed9f9cd2013-02-27 21:12:358654 uint32 immediate_data_size, const cmds::GetActiveUniform& c) {
[email protected]df37b9932013-03-08 05:21:428655 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258656 GLuint index = c.index;
8657 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358658 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:258659 Result* result = GetSharedMemoryAs<Result*>(
8660 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8661 if (!result) {
8662 return error::kOutOfBounds;
8663 }
[email protected]07d0cc82010-02-17 04:51:408664 // Check that the client initialized the result.
8665 if (result->success != 0) {
8666 return error::kInvalidArguments;
8667 }
[email protected]df37b9932013-03-08 05:21:428668 Program* program = GetProgramInfoNotShader(
8669 program_id, "glGetActiveUniform");
8670 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258671 return error::kNoError;
8672 }
[email protected]ed9f9cd2013-02-27 21:12:358673 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428674 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:258675 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:518676 LOCAL_SET_GL_ERROR(
8677 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258678 return error::kNoError;
8679 }
8680 result->success = 1; // true.
8681 result->size = uniform_info->size;
8682 result->type = uniform_info->type;
8683 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298684 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148685 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328686}
8687
[email protected]f7a64ee2010-02-01 22:24:148688error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]ed9f9cd2013-02-27 21:12:358689 uint32 immediate_data_size, const cmds::GetActiveAttrib& c) {
[email protected]df37b9932013-03-08 05:21:428690 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258691 GLuint index = c.index;
8692 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358693 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:258694 Result* result = GetSharedMemoryAs<Result*>(
8695 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8696 if (!result) {
8697 return error::kOutOfBounds;
8698 }
[email protected]07d0cc82010-02-17 04:51:408699 // Check that the client initialized the result.
8700 if (result->success != 0) {
8701 return error::kInvalidArguments;
8702 }
[email protected]df37b9932013-03-08 05:21:428703 Program* program = GetProgramInfoNotShader(
8704 program_id, "glGetActiveAttrib");
8705 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258706 return error::kNoError;
8707 }
[email protected]ed9f9cd2013-02-27 21:12:358708 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:428709 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:258710 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:518711 LOCAL_SET_GL_ERROR(
8712 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258713 return error::kNoError;
8714 }
8715 result->success = 1; // true.
8716 result->size = attrib_info->size;
8717 result->type = attrib_info->type;
8718 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298719 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148720 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328721}
8722
[email protected]b273e432010-04-12 17:23:588723error::Error GLES2DecoderImpl::HandleShaderBinary(
[email protected]ed9f9cd2013-02-27 21:12:358724 uint32 immediate_data_size, const cmds::ShaderBinary& c) {
[email protected]b273e432010-04-12 17:23:588725#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:518726 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:588727 return error::kNoError;
8728#else
8729 GLsizei n = static_cast<GLsizei>(c.n);
8730 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:518731 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:588732 return error::kNoError;
8733 }
8734 GLsizei length = static_cast<GLsizei>(c.length);
8735 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:518736 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:588737 return error::kNoError;
8738 }
8739 uint32 data_size;
8740 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
8741 return error::kOutOfBounds;
8742 }
8743 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
8744 c.shaders_shm_id, c.shaders_shm_offset, data_size);
8745 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
8746 const void* binary = GetSharedMemoryAs<const void*>(
8747 c.binary_shm_id, c.binary_shm_offset, length);
8748 if (shaders == NULL || binary == NULL) {
8749 return error::kOutOfBounds;
8750 }
8751 scoped_array<GLuint> service_ids(new GLuint[n]);
8752 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:428753 Shader* shader = GetShader(shaders[ii]);
8754 if (!shader) {
[email protected]ab09b612013-03-11 22:11:518755 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:588756 return error::kNoError;
8757 }
[email protected]df37b9932013-03-08 05:21:428758 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:588759 }
8760 // TODO(gman): call glShaderBinary
8761 return error::kNoError;
8762#endif
8763}
8764
[email protected]6217d392010-03-25 22:08:358765error::Error GLES2DecoderImpl::HandleSwapBuffers(
[email protected]ed9f9cd2013-02-27 21:12:358766 uint32 immediate_data_size, const cmds::SwapBuffers& c) {
[email protected]64ace852011-05-19 21:49:498767 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:088768
[email protected]64ace852011-05-19 21:49:498769 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:428770 // TRACE_EVENT for gpu tests:
8771 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:428772 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:428773 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
8774 "width", (is_offscreen ? offscreen_size_.width() :
8775 surface_->GetSize().width()));
[email protected]64ace852011-05-19 21:49:498776 TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleSwapBuffers",
8777 "offscreen", is_offscreen,
8778 "frame", this_frame_number);
[email protected]6217d392010-03-25 22:08:358779 // If offscreen then don't actually SwapBuffers to the display. Just copy
8780 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:498781 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:318782 TRACE_EVENT2("gpu", "Offscreen",
8783 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:538784 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
8785 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
8786 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
8787 // fix this.
[email protected]62e155e2012-10-23 22:43:158788 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:538789 offscreen_saved_frame_buffer_->Create();
8790 glFinish();
8791 }
8792
8793 // Allocate the offscreen saved color texture.
8794 DCHECK(offscreen_saved_color_format_);
8795 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:098796 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:538797
8798 offscreen_saved_frame_buffer_->AttachRenderTexture(
8799 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:058800 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
8801 if (offscreen_saved_frame_buffer_->CheckStatus() !=
8802 GL_FRAMEBUFFER_COMPLETE) {
8803 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
8804 << "because offscreen saved FBO was incomplete.";
8805 return error::kLostContext;
8806 }
[email protected]1fb8c482011-08-31 01:01:538807
[email protected]f0cfe752013-01-14 01:09:058808 // Clear the offscreen color texture.
8809 // TODO(piman): Is this still necessary?
8810 {
8811 ScopedFrameBufferBinder binder(this,
8812 offscreen_saved_frame_buffer_->id());
8813 glClearColor(0, 0, 0, 0);
8814 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
8815 glDisable(GL_SCISSOR_TEST);
8816 glClear(GL_COLOR_BUFFER_BIT);
8817 RestoreClearState();
8818 }
[email protected]1fb8c482011-08-31 01:01:538819 }
8820
8821 UpdateParentTextureInfo();
8822 }
8823
[email protected]f0cfe752013-01-14 01:09:058824 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
8825 return error::kNoError;
[email protected]ab09b612013-03-11 22:11:518826 ScopedGLErrorSuppressor suppressor(
8827 "GLES2DecoderImpl::HandleSwapBuffers", this);
[email protected]6217d392010-03-25 22:08:358828
[email protected]34ff8b0c2010-10-01 20:06:028829 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:138830 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:278831 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]89d6ed02011-04-20 00:23:238832 return error::kNoError;
[email protected]b86b14982010-10-11 18:45:488833 } else {
[email protected]069944672012-04-25 20:52:238834 ScopedFrameBufferBinder binder(this,
8835 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:138836
[email protected]069944672012-04-25 20:52:238837 if (offscreen_target_buffer_preserved_) {
8838 // Copy the target frame buffer to the saved offscreen texture.
8839 offscreen_saved_color_texture_->Copy(
8840 offscreen_saved_color_texture_->size(),
8841 offscreen_saved_color_format_);
8842 } else {
8843 // Flip the textures in the parent context via the texture manager.
8844 if (!!offscreen_saved_color_texture_info_.get())
8845 offscreen_saved_color_texture_info_->
8846 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:568847
[email protected]069944672012-04-25 20:52:238848 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
8849 offscreen_target_frame_buffer_->AttachRenderTexture(
8850 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:488851 }
[email protected]069944672012-04-25 20:52:238852
8853 // Ensure the side effects of the copy are visible to the parent
8854 // context. There is no need to do this for ANGLE because it uses a
8855 // single D3D device for all contexts.
8856 if (!IsAngle())
8857 glFlush();
[email protected]89d6ed02011-04-20 00:23:238858 return error::kNoError;
[email protected]0c8c9d22010-06-25 17:36:398859 }
[email protected]6217d392010-03-25 22:08:358860 } else {
[email protected]111975c62012-09-06 01:37:318861 TRACE_EVENT2("gpu", "Onscreen",
8862 "width", surface_->GetSize().width(),
8863 "height", surface_->GetSize().height());
[email protected]f62a5ab2011-05-23 20:34:158864 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:018865 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]5259ead82010-09-10 18:02:028866 return error::kLostContext;
[email protected]d0498742010-09-20 20:27:018867 }
[email protected]6217d392010-03-25 22:08:358868 }
8869
[email protected]89d6ed02011-04-20 00:23:238870 return error::kNoError;
[email protected]6217d392010-03-25 22:08:358871}
8872
[email protected]d4239852011-08-12 04:51:228873error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358874 uint32 immediate_data_size, const cmds::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:188875 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288876 if (!bucket || bucket->size() == 0) {
8877 return error::kInvalidArguments;
8878 }
[email protected]ed9f9cd2013-02-27 21:12:358879 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:188880 Result* result = GetSharedMemoryAs<Result*>(
8881 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8882 if (!result) {
8883 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:108884 }
[email protected]b1d2dcb2010-05-17 19:24:188885 // Check that the client initialized the result.
8886 if (*result != 0) {
8887 return error::kInvalidArguments;
8888 }
8889 std::string feature_str;
8890 if (!bucket->GetAsString(&feature_str)) {
8891 return error::kInvalidArguments;
8892 }
8893
8894 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:228895 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:188896 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:228897 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:408898 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
8899 // TODO(gman): decide how to remove the need for this const_cast.
8900 // I could make validators_ non const but that seems bad as this is the only
8901 // place it is needed. I could make some special friend class of validators
8902 // just to allow this to set them. That seems silly. I could refactor this
8903 // code to use the extension mechanism or the initialization attributes to
8904 // turn this feature on. Given that the only real point of this is to make
8905 // the conformance tests pass and given that there is lots of real work that
8906 // needs to be done it seems like refactoring for one to one of those
8907 // methods is a very low priority.
8908 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:048909 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
8910 force_webgl_glsl_validation_ = true;
8911 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:188912 } else {
8913 return error::kNoError;
8914 }
8915
8916 *result = 1; // true.
8917 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:108918}
8919
[email protected]c2f8c8402010-12-06 18:07:248920error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
8921 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:358922 const cmds::GetRequestableExtensionsCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:248923 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:358924 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]e82fb792011-09-22 00:33:298925 info->Initialize(disallowed_features_, NULL);
[email protected]c2f8c8402010-12-06 18:07:248926 bucket->SetFromString(info->extensions().c_str());
8927 return error::kNoError;
8928}
8929
8930error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358931 uint32 immediate_data_size, const cmds::RequestExtensionCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:248932 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288933 if (!bucket || bucket->size() == 0) {
8934 return error::kInvalidArguments;
8935 }
[email protected]c2f8c8402010-12-06 18:07:248936 std::string feature_str;
8937 if (!bucket->GetAsString(&feature_str)) {
8938 return error::kInvalidArguments;
8939 }
8940
[email protected]4b7eba92013-01-08 02:23:568941 bool desire_webgl_glsl_validation =
8942 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
8943 bool desire_standard_derivatives = false;
8944 if (force_webgl_glsl_validation_) {
8945 desire_standard_derivatives =
8946 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:048947 }
8948
[email protected]4b7eba92013-01-08 02:23:568949 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
8950 desire_standard_derivatives != derivatives_explicitly_enabled_) {
8951 force_webgl_glsl_validation_ = desire_webgl_glsl_validation;
8952 derivatives_explicitly_enabled_ = desire_standard_derivatives;
[email protected]c2f8c8402010-12-06 18:07:248953 InitializeShaderTranslator();
8954 }
8955
[email protected]302ce6d2011-07-07 23:28:118956 UpdateCapabilities();
8957
[email protected]c2f8c8402010-12-06 18:07:248958 return error::kNoError;
8959}
8960
[email protected]372e0412011-06-28 16:08:568961error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358962 uint32 immediate_data_size, const cmds::GetMultipleIntegervCHROMIUM& c) {
[email protected]372e0412011-06-28 16:08:568963 GLuint count = c.count;
8964 uint32 pnames_size;
8965 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
8966 return error::kOutOfBounds;
8967 }
8968 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
8969 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
8970 if (pnames == NULL) {
8971 return error::kOutOfBounds;
8972 }
8973
8974 // We have to copy them since we use them twice so the client
8975 // can't change them between the time we validate them and the time we use
8976 // them.
[email protected]40d90a22013-04-09 03:39:558977 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:568978 memcpy(enums.get(), pnames, pnames_size);
8979
8980 // Count up the space needed for the result.
8981 uint32 num_results = 0;
8982 for (GLuint ii = 0; ii < count; ++ii) {
8983 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
8984 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:518985 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8986 "glGetMulitpleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:568987 return error::kNoError;
8988 }
8989 // Num will never be more than 4.
8990 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:478991 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:568992 return error::kOutOfBounds;
8993 }
8994 }
8995
8996 uint32 result_size = 0;
8997 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
8998 return error::kOutOfBounds;
8999 }
9000
9001 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:519002 LOCAL_SET_GL_ERROR(
9003 GL_INVALID_VALUE,
9004 "glGetMulitpleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:569005 return error::kNoError;
9006 }
9007
9008 GLint* results = GetSharedMemoryAs<GLint*>(
9009 c.results_shm_id, c.results_shm_offset, result_size);
9010 if (results == NULL) {
9011 return error::kOutOfBounds;
9012 }
9013
9014 // Check the results have been cleared in case the context was lost.
9015 for (uint32 ii = 0; ii < num_results; ++ii) {
9016 if (results[ii]) {
9017 return error::kInvalidArguments;
9018 }
9019 }
9020
9021 // Get each result.
9022 GLint* start = results;
9023 for (GLuint ii = 0; ii < count; ++ii) {
9024 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:269025 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:539026 !GetHelper(enums[ii], results, &num_written)) {
[email protected]372e0412011-06-28 16:08:569027 glGetIntegerv(enums[ii], results);
9028 }
9029 results += num_written;
9030 }
9031
9032 // Just to verify. Should this be a DCHECK?
9033 if (static_cast<uint32>(results - start) != num_results) {
9034 return error::kOutOfBounds;
9035 }
9036
9037 return error::kNoError;
9038}
9039
[email protected]2318d342011-07-11 22:27:429040error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359041 uint32 immediate_data_size, const cmds::GetProgramInfoCHROMIUM& c) {
[email protected]df37b9932013-03-08 05:21:429042 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:429043 uint32 bucket_id = c.bucket_id;
9044 Bucket* bucket = CreateBucket(bucket_id);
9045 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:429046 Program* program = NULL;
9047 program = GetProgram(program_id);
9048 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:469049 return error::kNoError;
[email protected]2318d342011-07-11 22:27:429050 }
[email protected]df37b9932013-03-08 05:21:429051 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:429052 return error::kNoError;
9053}
9054
[email protected]38d139d2011-07-14 00:38:439055error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9056 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:439057 case GL_NO_ERROR:
9058 // TODO(kbr): improve the precision of the error code in this case.
9059 // Consider delegating to context for error code if MakeCurrent fails.
9060 return error::kUnknown;
9061 case GL_GUILTY_CONTEXT_RESET_ARB:
9062 return error::kGuilty;
9063 case GL_INNOCENT_CONTEXT_RESET_ARB:
9064 return error::kInnocent;
9065 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9066 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439067 }
9068
9069 NOTREACHED();
9070 return error::kUnknown;
9071}
9072
9073bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099074 if (reset_status_ != GL_NO_ERROR) {
9075 return true;
9076 }
[email protected]706b69f2012-07-27 04:59:309077 if (context_->WasAllocatedUsingRobustnessExtension()) {
9078 GLenum status = GL_NO_ERROR;
9079 if (has_robustness_extension_)
9080 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439081 if (status != GL_NO_ERROR) {
9082 // The graphics card was reset. Signal a lost context to the application.
9083 reset_status_ = status;
9084 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099085 << " context lost via ARB/EXT_robustness. Reset status = "
9086 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:439087 return true;
9088 }
9089 }
9090 return false;
9091}
9092
[email protected]c4485aad62012-12-17 10:19:099093void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9094 // Only loses the context once.
9095 if (reset_status_ != GL_NO_ERROR) {
9096 return;
9097 }
9098
9099 // Marks this context as lost.
9100 reset_status_ = reset_status;
9101 current_decoder_error_ = error::kLostContext;
9102
9103 // Loses the parent's context.
9104 if (parent_) {
9105 parent_->LoseContext(reset_status);
9106 }
9107
9108 // Loses any child contexts.
9109 for (ChildList::iterator it = children_.begin();
9110 it != children_.end();
9111 ++it) {
9112 (*it)->LoseContext(reset_status);
9113 }
9114}
9115
9116error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359117 uint32 immediate_data_size, const cmds::LoseContextCHROMIUM& c) {
[email protected]c4485aad62012-12-17 10:19:099118 GLenum current = static_cast<GLenum>(c.current);
9119 GLenum other = static_cast<GLenum>(c.other);
9120 if (!validators_->reset_status.IsValid(current)) {
[email protected]ab09b612013-03-11 22:11:519121 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9122 "glLoseContextCHROMIUM", current, "current");
[email protected]c4485aad62012-12-17 10:19:099123 }
9124 if (!validators_->reset_status.IsValid(other)) {
[email protected]ab09b612013-03-11 22:11:519125 LOCAL_SET_GL_ERROR_INVALID_ENUM("glLoseContextCHROMIUM", other, "other");
[email protected]c4485aad62012-12-17 10:19:099126 }
9127 group_->LoseContexts(other);
9128 reset_status_ = current;
9129 current_decoder_error_ = error::kLostContext;
9130 return error::kLostContext;
9131}
9132
[email protected]b096d032013-03-08 03:08:019133error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
9134 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) {
9135 return error::kUnknownCommand;
9136}
9137
[email protected]840a7e462013-02-27 01:29:519138error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359139 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) {
[email protected]840a7e462013-02-27 01:29:519140 if (wait_sync_point_callback_.is_null())
9141 return error::kNoError;
9142
9143 return wait_sync_point_callback_.Run(c.sync_point) ?
9144 error::kNoError : error::kDeferCommandUntilLater;
9145}
9146
[email protected]882ba1e22012-03-08 19:02:539147bool GLES2DecoderImpl::GenQueriesEXTHelper(
9148 GLsizei n, const GLuint* client_ids) {
9149 for (GLsizei ii = 0; ii < n; ++ii) {
9150 if (query_manager_->GetQuery(client_ids[ii])) {
9151 return false;
9152 }
9153 }
[email protected]c45f1972012-03-14 07:27:369154 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
[email protected]882ba1e22012-03-08 19:02:539155 return true;
9156}
9157
9158void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9159 GLsizei n, const GLuint* client_ids) {
9160 for (GLsizei ii = 0; ii < n; ++ii) {
9161 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9162 if (query && !query->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:249163 if (query == state_.current_query) {
9164 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539165 }
[email protected]c45f1972012-03-14 07:27:369166 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539167 query_manager_->RemoveQuery(client_ids[ii]);
9168 }
9169 }
9170}
9171
[email protected]22e3f552012-03-13 01:54:199172bool GLES2DecoderImpl::ProcessPendingQueries() {
9173 if (query_manager_.get() == NULL) {
9174 return false;
9175 }
[email protected]c45f1972012-03-14 07:27:369176 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:199177 current_decoder_error_ = error::kOutOfBounds;
9178 }
9179 return query_manager_->HavePendingQueries();
9180}
9181
[email protected]2b1767cf2013-03-16 09:25:059182bool GLES2DecoderImpl::HasMoreIdleWork() {
9183 return async_pixel_transfer_delegate_->NeedsProcessMorePendingTransfers();
9184}
9185
9186void GLES2DecoderImpl::PerformIdleWork() {
9187 if (!async_pixel_transfer_delegate_->NeedsProcessMorePendingTransfers())
9188 return;
9189 // TODO(reveman): We should avoid using a bool return value to determine
9190 // if we need to restore some state. crbug.com/196303
9191 if (async_pixel_transfer_delegate_->ProcessMorePendingTransfers())
9192 RestoreCurrentTexture2DBindings();
9193 ProcessFinishedAsyncTransfers();
9194}
9195
[email protected]882ba1e22012-03-08 19:02:539196error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359197 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539198 GLenum target = static_cast<GLenum>(c.target);
9199 GLuint client_id = static_cast<GLuint>(c.id);
9200 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9201 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9202
[email protected]c45f1972012-03-14 07:27:369203 switch (target) {
9204 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559205 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]0713f43d2012-12-14 22:41:309206 case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009207 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369208 break;
9209 default:
[email protected]62e155e2012-10-23 22:43:159210 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519211 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009212 GL_INVALID_OPERATION, "glBeginQueryEXT",
9213 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369214 return error::kNoError;
9215 }
9216 break;
[email protected]882ba1e22012-03-08 19:02:539217 }
9218
[email protected]e259eb412012-10-13 05:47:249219 if (state_.current_query) {
[email protected]ab09b612013-03-11 22:11:519220 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439221 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539222 return error::kNoError;
9223 }
9224
9225 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519226 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539227 return error::kNoError;
9228 }
9229
9230 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9231 if (!query) {
[email protected]c45f1972012-03-14 07:27:369232 // TODO(gman): Decide if we need this check.
9233 //
[email protected]882ba1e22012-03-08 19:02:539234 // Checks id was made by glGenQueries
[email protected]c45f1972012-03-14 07:27:369235 //
9236 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
9237 // for all Query ids but from the POV of the command buffer service maybe
9238 // you don't.
9239 //
9240 // The client can enforce this. I don't think the service cares.
9241 //
9242 // IdAllocatorInterface* id_allocator =
9243 // group_->GetIdAllocator(id_namespaces::kQueries);
9244 // if (!id_allocator->InUse(client_id)) {
[email protected]ab09b612013-03-11 22:11:519245 // LOCAL_SET_GL_ERROR(
9246 // GL_INVALID_OPERATION,
9247 // "glBeginQueryEXT", "id not made by glGenQueriesEXT");
[email protected]c45f1972012-03-14 07:27:369248 // return error::kNoError;
9249 // }
9250 query = query_manager_->CreateQuery(
9251 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539252 }
9253
[email protected]c45f1972012-03-14 07:27:369254 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519255 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439256 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539257 return error::kNoError;
9258 } else if (query->shm_id() != sync_shm_id ||
9259 query->shm_offset() != sync_shm_offset) {
9260 DLOG(ERROR) << "Shared memory used by query not the same as before";
9261 return error::kInvalidArguments;
9262 }
9263
[email protected]c45f1972012-03-14 07:27:369264 if (!query_manager_->BeginQuery(query)) {
9265 return error::kOutOfBounds;
9266 }
[email protected]882ba1e22012-03-08 19:02:539267
[email protected]e259eb412012-10-13 05:47:249268 state_.current_query = query;
[email protected]882ba1e22012-03-08 19:02:539269 return error::kNoError;
9270}
9271
9272error::Error GLES2DecoderImpl::HandleEndQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359273 uint32 immediate_data_size, const cmds::EndQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539274 GLenum target = static_cast<GLenum>(c.target);
9275 uint32 submit_count = static_cast<GLuint>(c.submit_count);
9276
[email protected]e259eb412012-10-13 05:47:249277 if (!state_.current_query) {
[email protected]ab09b612013-03-11 22:11:519278 LOCAL_SET_GL_ERROR(
9279 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539280 return error::kNoError;
9281 }
[email protected]e259eb412012-10-13 05:47:249282 if (state_.current_query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519283 LOCAL_SET_GL_ERROR(
9284 GL_INVALID_OPERATION,
9285 "glEndQueryEXT", "target does not match active query");
[email protected]882ba1e22012-03-08 19:02:539286 return error::kNoError;
9287 }
[email protected]882ba1e22012-03-08 19:02:539288
[email protected]e259eb412012-10-13 05:47:249289 if (!query_manager_->EndQuery(state_.current_query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:369290 return error::kOutOfBounds;
9291 }
9292
[email protected]fe8d73c2013-02-16 22:37:329293 query_manager_->ProcessPendingTransferQueries();
9294
[email protected]e259eb412012-10-13 05:47:249295 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539296 return error::kNoError;
9297}
9298
[email protected]944b62f32012-09-27 02:20:469299bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9300 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469301 for (GLsizei ii = 0; ii < n; ++ii) {
9302 if (GetVertexAttribManager(client_ids[ii])) {
9303 return false;
9304 }
9305 }
[email protected]ab4fd7282012-10-12 16:25:579306
[email protected]62e155e2012-10-23 22:43:159307 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579308 // Emulated VAO
9309 for (GLsizei ii = 0; ii < n; ++ii) {
9310 CreateVertexAttribManager(client_ids[ii], 0);
9311 }
9312 } else {
[email protected]40d90a22013-04-09 03:39:559313 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:579314
9315 glGenVertexArraysOES(n, service_ids.get());
9316 for (GLsizei ii = 0; ii < n; ++ii) {
9317 CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
9318 }
[email protected]944b62f32012-09-27 02:20:469319 }
[email protected]ab4fd7282012-10-12 16:25:579320
[email protected]944b62f32012-09-27 02:20:469321 return true;
9322}
9323
9324void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9325 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469326 for (GLsizei ii = 0; ii < n; ++ii) {
9327 VertexAttribManager* vao =
9328 GetVertexAttribManager(client_ids[ii]);
9329 if (vao && !vao->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:249330 if (state_.vertex_attrib_manager == vao) {
9331 state_.vertex_attrib_manager = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469332 }
9333 RemoveVertexAttribManager(client_ids[ii]);
9334 }
9335 }
9336}
9337
9338void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469339 VertexAttribManager* vao = NULL;
9340 GLuint service_id = 0;
9341 if (client_id != 0) {
9342 vao = GetVertexAttribManager(client_id);
9343 if (!vao) {
9344 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9345 // only allows names that have been previously generated. As such, we do
9346 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:519347 LOCAL_SET_GL_ERROR(
9348 GL_INVALID_OPERATION,
9349 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:469350 current_decoder_error_ = error::kNoError;
9351 return;
9352 } else {
9353 service_id = vao->service_id();
9354 }
[email protected]944b62f32012-09-27 02:20:469355 } else {
[email protected]ab4fd7282012-10-12 16:25:579356 vao = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469357 }
9358
[email protected]ab4fd7282012-10-12 16:25:579359 // Only set the VAO state if it's changed
[email protected]e259eb412012-10-13 05:47:249360 if (state_.vertex_attrib_manager != vao) {
9361 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:159362 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579363 EmulateVertexArrayState();
9364 } else {
9365 glBindVertexArrayOES(service_id);
9366 }
9367 }
9368}
9369
9370// Used when OES_vertex_array_object isn't natively supported
9371void GLES2DecoderImpl::EmulateVertexArrayState() {
9372 // Setup the Vertex attribute state
9373 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
9374 RestoreStateForAttrib(vv);
9375 }
9376
9377 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:219378 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:249379 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:579380 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9381 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:469382}
9383
9384bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469385 const VertexAttribManager* vao =
9386 GetVertexAttribManager(client_id);
9387 return vao && vao->IsValid() && !vao->IsDeleted();
9388}
9389
[email protected]b0af4f52011-09-28 22:04:429390error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM(
9391 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359392 const cmds::CreateStreamTextureCHROMIUM& c) {
[email protected]62e155e2012-10-23 22:43:159393 if (!features().chromium_stream_texture) {
[email protected]ab09b612013-03-11 22:11:519394 LOCAL_SET_GL_ERROR(
9395 GL_INVALID_OPERATION,
9396 "glOpenStreamTextureCHROMIUM", "not supported.");
[email protected]b0af4f52011-09-28 22:04:429397 return error::kNoError;
9398 }
9399
9400 uint32 client_id = c.client_id;
[email protected]ed9f9cd2013-02-27 21:12:359401 typedef cmds::CreateStreamTextureCHROMIUM::Result Result;
[email protected]b0af4f52011-09-28 22:04:429402 Result* result = GetSharedMemoryAs<Result*>(
9403 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9404
[email protected]e5081262012-01-05 23:09:039405 if (!result)
9406 return error::kOutOfBounds;
[email protected]b0af4f52011-09-28 22:04:429407 *result = GL_ZERO;
[email protected]02965c22013-03-09 02:40:079408 Texture* texture = texture_manager()->GetTexture(client_id);
9409 if (!texture) {
[email protected]ab09b612013-03-11 22:11:519410 LOCAL_SET_GL_ERROR(
9411 GL_INVALID_VALUE,
9412 "glCreateStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429413 return error::kNoError;
9414 }
9415
[email protected]02965c22013-03-09 02:40:079416 if (texture->IsStreamTexture()) {
[email protected]ab09b612013-03-11 22:11:519417 LOCAL_SET_GL_ERROR(
9418 GL_INVALID_OPERATION,
9419 "glCreateStreamTextureCHROMIUM", "is already a stream texture.");
[email protected]b0af4f52011-09-28 22:04:429420 return error::kNoError;
9421 }
9422
[email protected]02965c22013-03-09 02:40:079423 if (texture->target() && texture->target() != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:519424 LOCAL_SET_GL_ERROR(
9425 GL_INVALID_OPERATION,
9426 "glCreateStreamTextureCHROMIUM",
9427 "is already bound to incompatible target.");
[email protected]b0af4f52011-09-28 22:04:429428 return error::kNoError;
9429 }
9430
9431 if (!stream_texture_manager_)
9432 return error::kInvalidArguments;
9433
9434 GLuint object_id = stream_texture_manager_->CreateStreamTexture(
[email protected]02965c22013-03-09 02:40:079435 texture->service_id(), client_id);
[email protected]b0af4f52011-09-28 22:04:429436
9437 if (object_id) {
[email protected]02965c22013-03-09 02:40:079438 texture->SetStreamTexture(true);
[email protected]b0af4f52011-09-28 22:04:429439 } else {
[email protected]ab09b612013-03-11 22:11:519440 LOCAL_SET_GL_ERROR(
9441 GL_OUT_OF_MEMORY,
9442 "glCreateStreamTextureCHROMIUM", "failed to create platform texture.");
[email protected]b0af4f52011-09-28 22:04:429443 }
9444
9445 *result = object_id;
9446 return error::kNoError;
9447}
9448
9449error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM(
9450 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359451 const cmds::DestroyStreamTextureCHROMIUM& c) {
[email protected]b0af4f52011-09-28 22:04:429452 GLuint client_id = c.texture;
[email protected]02965c22013-03-09 02:40:079453 Texture* texture = texture_manager()->GetTexture(client_id);
9454 if (texture && texture->IsStreamTexture()) {
[email protected]b0af4f52011-09-28 22:04:429455 if (!stream_texture_manager_)
9456 return error::kInvalidArguments;
9457
[email protected]02965c22013-03-09 02:40:079458 stream_texture_manager_->DestroyStreamTexture(texture->service_id());
9459 texture->SetStreamTexture(false);
[email protected]b0af4f52011-09-28 22:04:429460 } else {
[email protected]ab09b612013-03-11 22:11:519461 LOCAL_SET_GL_ERROR(
9462 GL_INVALID_VALUE,
9463 "glDestroyStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429464 }
9465
9466 return error::kNoError;
9467}
9468
[email protected]e51bdf32011-11-23 22:21:469469#if defined(OS_MACOSX)
9470void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9471 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9472 texture_id);
9473 if (it != texture_to_io_surface_map_.end()) {
9474 // Found a previous IOSurface bound to this texture; release it.
9475 CFTypeRef surface = it->second;
9476 CFRelease(surface);
9477 texture_to_io_surface_map_.erase(it);
9478 }
9479}
9480#endif
9481
9482void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9483 GLenum target, GLsizei width, GLsizei height,
9484 GLuint io_surface_id, GLuint plane) {
9485#if defined(OS_MACOSX)
9486 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:519487 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439488 GL_INVALID_OPERATION,
9489 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:469490 return;
9491 }
9492
9493 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize();
9494 if (!surface_support) {
[email protected]ab09b612013-03-11 22:11:519495 LOCAL_SET_GL_ERROR(
9496 GL_INVALID_OPERATION,
9497 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6.");
[email protected]e51bdf32011-11-23 22:21:469498 return;
9499 }
9500
9501 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9502 // This might be supported in the future, and if we could require
9503 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9504 // could delete a lot of code. For now, perform strict validation so we
9505 // know what's going on.
[email protected]ab09b612013-03-11 22:11:519506 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469507 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439508 "glTexImageIOSurface2DCHROMIUM",
9509 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:469510 return;
9511 }
9512
[email protected]09d50362012-10-18 20:54:379513 // Default target might be conceptually valid, but disallow it to avoid
9514 // accidents.
[email protected]02965c22013-03-09 02:40:079515 Texture* texture = GetTextureInfoForTargetUnlessDefault(target);
9516 if (!texture) {
[email protected]ab09b612013-03-11 22:11:519517 LOCAL_SET_GL_ERROR(
9518 GL_INVALID_OPERATION,
9519 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:469520 return;
9521 }
[email protected]e51bdf32011-11-23 22:21:469522
9523 // Look up the new IOSurface. Note that because of asynchrony
9524 // between processes this might fail; during live resizing the
9525 // plugin process might allocate and release an IOSurface before
9526 // this process gets a chance to look it up. Hold on to any old
9527 // IOSurface in this case.
9528 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id);
9529 if (!surface) {
[email protected]ab09b612013-03-11 22:11:519530 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439531 GL_INVALID_OPERATION,
9532 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:469533 return;
9534 }
9535
9536 // Release any IOSurface previously bound to this texture.
[email protected]02965c22013-03-09 02:40:079537 ReleaseIOSurfaceForTexture(texture->service_id());
[email protected]e51bdf32011-11-23 22:21:469538
9539 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9540 texture_to_io_surface_map_.insert(
[email protected]02965c22013-03-09 02:40:079541 std::make_pair(texture->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:469542
9543 CGLContextObj context =
9544 static_cast<CGLContextObj>(context_->GetHandle());
9545
9546 CGLError err = surface_support->CGLTexImageIOSurface2D(
9547 context,
9548 target,
9549 GL_RGBA,
9550 width,
9551 height,
9552 GL_BGRA,
9553 GL_UNSIGNED_INT_8_8_8_8_REV,
9554 surface,
9555 plane);
9556
9557 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:519558 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469559 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439560 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:469561 return;
9562 }
9563
9564 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:079565 texture, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:469566 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9567
9568#else
[email protected]ab09b612013-03-11 22:11:519569 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439570 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:469571#endif
9572}
9573
[email protected]97dc7cbe2011-12-06 17:26:179574static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9575 switch (internalformat) {
9576 case GL_RGB565:
9577 return GL_RGB;
9578 case GL_RGBA4:
9579 return GL_RGBA;
9580 case GL_RGB5_A1:
9581 return GL_RGBA;
9582 case GL_RGB8_OES:
9583 return GL_RGB;
9584 case GL_RGBA8_OES:
9585 return GL_RGBA;
9586 case GL_LUMINANCE8_ALPHA8_EXT:
9587 return GL_LUMINANCE_ALPHA;
9588 case GL_LUMINANCE8_EXT:
9589 return GL_LUMINANCE;
9590 case GL_ALPHA8_EXT:
9591 return GL_ALPHA;
9592 case GL_RGBA32F_EXT:
9593 return GL_RGBA;
9594 case GL_RGB32F_EXT:
9595 return GL_RGB;
9596 case GL_ALPHA32F_EXT:
9597 return GL_ALPHA;
9598 case GL_LUMINANCE32F_EXT:
9599 return GL_LUMINANCE;
9600 case GL_LUMINANCE_ALPHA32F_EXT:
9601 return GL_LUMINANCE_ALPHA;
9602 case GL_RGBA16F_EXT:
9603 return GL_RGBA;
9604 case GL_RGB16F_EXT:
9605 return GL_RGB;
9606 case GL_ALPHA16F_EXT:
9607 return GL_ALPHA;
9608 case GL_LUMINANCE16F_EXT:
9609 return GL_LUMINANCE;
9610 case GL_LUMINANCE_ALPHA16F_EXT:
9611 return GL_LUMINANCE_ALPHA;
9612 case GL_BGRA8_EXT:
9613 return GL_BGRA_EXT;
9614 default:
9615 return GL_NONE;
9616 }
9617}
9618
[email protected]43410e92012-04-20 17:06:289619void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:039620 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
9621 GLenum internal_format) {
[email protected]02965c22013-03-09 02:40:079622 Texture* dest_texture = GetTexture(dest_id);
9623 Texture* source_texture = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:289624
[email protected]02965c22013-03-09 02:40:079625 if (!source_texture || !dest_texture) {
[email protected]ab09b612013-03-11 22:11:519626 LOCAL_SET_GL_ERROR(
9627 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:289628 return;
9629 }
9630
9631 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:519632 LOCAL_SET_GL_ERROR(
9633 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:289634 return;
9635 }
9636
[email protected]02965c22013-03-09 02:40:079637 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:259638 (source_texture->target() != GL_TEXTURE_2D &&
9639 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]ab09b612013-03-11 22:11:519640 LOCAL_SET_GL_ERROR(
9641 GL_INVALID_VALUE,
9642 "glCopyTextureCHROMIUM", "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:039643 return;
9644 }
9645
[email protected]43410e92012-04-20 17:06:289646 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:289647
[email protected]9bc9a2e82013-04-03 03:56:259648 // When the source texture is GL_TEXTURE_EXTERNAL_OES, we assume width
9649 // and height are the same as destination texture. The caller needs to
9650 // make sure they allocate a destination texture which is the same size
9651 // as the source. This is due to the limitation of the StreamTexture.
9652 // There is no way to find out the size of the texture from the GL consumer
9653 // side. But StreamTextures are unique per video stream and should never
9654 // change, so we could find out the size of the video stream and allocate
9655 // a equal size RGBA texture for copy. TODO(hkuang): Add support to get
9656 // width/height of StreamTexture crbug.com/225781.
9657 if (source_texture->target() == GL_TEXTURE_2D) {
9658 if (!source_texture->GetLevelSize(GL_TEXTURE_2D, 0, &source_width,
9659 &source_height)) {
9660 LOCAL_SET_GL_ERROR(
9661 GL_INVALID_VALUE,
9662 "glCopyTextureChromium", "source texture has no level 0");
9663 return;
9664 }
9665
9666 // Check that this type of texture is allowed.
9667 if (!texture_manager()->ValidForTarget(GL_TEXTURE_2D, level, source_width,
9668 source_height, 1)) {
9669 LOCAL_SET_GL_ERROR(
9670 GL_INVALID_VALUE,
9671 "glCopyTextureCHROMIUM", "Bad dimensions");
9672 return;
9673 }
[email protected]43410e92012-04-20 17:06:289674 }
9675
[email protected]cf6b8f62012-05-25 21:43:379676 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9677 // needed because it takes 10s of milliseconds to initialize.
9678 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:519679 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:379680 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:279681 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:379682 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:519683 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:379684 return;
9685 }
9686
[email protected]0a1e9ad2012-05-04 21:13:039687 GLenum dest_type;
9688 GLenum dest_internal_format;
[email protected]02965c22013-03-09 02:40:079689 bool dest_level_defined = dest_texture->GetLevelSize(
9690 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:289691
[email protected]0a1e9ad2012-05-04 21:13:039692 if (dest_level_defined) {
[email protected]02965c22013-03-09 02:40:079693 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type,
9694 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:039695 } else {
9696 GLenum source_internal_format;
[email protected]02965c22013-03-09 02:40:079697 source_texture->GetLevelType(GL_TEXTURE_2D, 0, &dest_type,
9698 &source_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:039699 }
9700
[email protected]9bc9a2e82013-04-03 03:56:259701 // Set source texture's width and height to be the same as
9702 // destination texture when source is GL_TEXTURE_EXTERNAL_OES.
9703 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9704 source_width = dest_width;
9705 source_height = dest_height;
9706 }
9707
[email protected]0a1e9ad2012-05-04 21:13:039708 // Resize the destination texture to the dimensions of the source texture.
9709 if (!dest_level_defined || dest_width != source_width ||
9710 dest_height != source_height ||
9711 dest_internal_format != internal_format) {
[email protected]43410e92012-04-20 17:06:289712 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:519713 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:079714 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]43410e92012-04-20 17:06:289715 WrappedTexImage2D(
9716 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:039717 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:519718 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:039719 if (error != GL_NO_ERROR) {
9720 RestoreCurrentTexture2DBindings();
[email protected]43410e92012-04-20 17:06:289721 return;
[email protected]0a1e9ad2012-05-04 21:13:039722 }
[email protected]43410e92012-04-20 17:06:289723
9724 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:079725 dest_texture, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:039726 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:259727 } else {
[email protected]02965c22013-03-09 02:40:079728 texture_manager()->SetLevelCleared(
9729 dest_texture, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:289730 }
9731
[email protected]5394a4102013-04-18 05:41:379732 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
9733 // before presenting.
9734 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9735 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
9736 // instead of using default matrix crbug.com/226218.
9737 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
9738 0.0f, 1.0f, 0.0f, 0.0f,
9739 0.0f, 0.0f, 1.0f, 0.0f,
9740 0.0f, 0.0f, 0.0f, 1.0f};
9741 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
9742 this,
9743 source_texture->target(),
9744 dest_texture->target(),
9745 source_texture->service_id(),
9746 dest_texture->service_id(), level,
9747 source_width, source_height,
9748 unpack_flip_y_,
9749 unpack_premultiply_alpha_,
9750 unpack_unpremultiply_alpha_,
9751 default_matrix);
9752 } else {
9753 copy_texture_CHROMIUM_->DoCopyTexture(
9754 this,
9755 source_texture->target(),
9756 dest_texture->target(),
9757 source_texture->service_id(),
9758 dest_texture->service_id(), level,
9759 source_width, source_height,
9760 unpack_flip_y_,
9761 unpack_premultiply_alpha_,
9762 unpack_unpremultiply_alpha_);
9763 }
[email protected]43410e92012-04-20 17:06:289764}
9765
[email protected]97dc7cbe2011-12-06 17:26:179766static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
9767 switch (internalformat) {
9768 case GL_RGB565:
9769 return GL_UNSIGNED_SHORT_5_6_5;
9770 case GL_RGBA4:
9771 return GL_UNSIGNED_SHORT_4_4_4_4;
9772 case GL_RGB5_A1:
9773 return GL_UNSIGNED_SHORT_5_5_5_1;
9774 case GL_RGB8_OES:
9775 return GL_UNSIGNED_BYTE;
9776 case GL_RGBA8_OES:
9777 return GL_UNSIGNED_BYTE;
9778 case GL_LUMINANCE8_ALPHA8_EXT:
9779 return GL_UNSIGNED_BYTE;
9780 case GL_LUMINANCE8_EXT:
9781 return GL_UNSIGNED_BYTE;
9782 case GL_ALPHA8_EXT:
9783 return GL_UNSIGNED_BYTE;
9784 case GL_RGBA32F_EXT:
9785 return GL_FLOAT;
9786 case GL_RGB32F_EXT:
9787 return GL_FLOAT;
9788 case GL_ALPHA32F_EXT:
9789 return GL_FLOAT;
9790 case GL_LUMINANCE32F_EXT:
9791 return GL_FLOAT;
9792 case GL_LUMINANCE_ALPHA32F_EXT:
9793 return GL_FLOAT;
9794 case GL_RGBA16F_EXT:
9795 return GL_HALF_FLOAT_OES;
9796 case GL_RGB16F_EXT:
9797 return GL_HALF_FLOAT_OES;
9798 case GL_ALPHA16F_EXT:
9799 return GL_HALF_FLOAT_OES;
9800 case GL_LUMINANCE16F_EXT:
9801 return GL_HALF_FLOAT_OES;
9802 case GL_LUMINANCE_ALPHA16F_EXT:
9803 return GL_HALF_FLOAT_OES;
9804 case GL_BGRA8_EXT:
9805 return GL_UNSIGNED_BYTE;
9806 default:
9807 return GL_NONE;
9808 }
9809}
9810
9811void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:449812 GLenum target,
9813 GLint levels,
9814 GLenum internal_format,
9815 GLsizei width,
9816 GLsizei height) {
[email protected]43ed3a72012-05-30 22:55:389817 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT");
[email protected]80eb6b52012-01-19 00:14:419818 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]97dc7cbe2011-12-06 17:26:179819 TextureManager::ComputeMipMapCount(width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:519820 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439821 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:179822 return;
9823 }
[email protected]02965c22013-03-09 02:40:079824 Texture* texture = GetTextureInfoForTarget(target);
9825 if (!texture) {
[email protected]ab09b612013-03-11 22:11:519826 LOCAL_SET_GL_ERROR(
9827 GL_INVALID_OPERATION,
9828 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:179829 return;
9830 }
[email protected]02965c22013-03-09 02:40:079831 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:429832 clear_state_dirty_ = true;
[email protected]97dc7cbe2011-12-06 17:26:179833 }
[email protected]02965c22013-03-09 02:40:079834 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519835 LOCAL_SET_GL_ERROR(
9836 GL_INVALID_OPERATION,
9837 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:179838 return;
9839 }
[email protected]7989c9e2013-01-23 06:39:269840
9841 GLenum format = ExtractFormatFromStorageFormat(internal_format);
9842 GLenum type = ExtractTypeFromStorageFormat(internal_format);
9843
9844 {
9845 GLsizei level_width = width;
9846 GLsizei level_height = height;
9847 uint32 estimated_size = 0;
9848 for (int ii = 0; ii < levels; ++ii) {
9849 uint32 level_size = 0;
9850 if (!GLES2Util::ComputeImageDataSizes(
9851 level_width, level_height, format, type, state_.unpack_alignment,
9852 &estimated_size, NULL, NULL) ||
9853 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519854 LOCAL_SET_GL_ERROR(
9855 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269856 return;
9857 }
9858 level_width = std::max(1, level_width >> 1);
9859 level_height = std::max(1, level_height >> 1);
9860 }
9861 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519862 LOCAL_SET_GL_ERROR(
9863 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:269864 return;
9865 }
9866 }
9867
[email protected]ab09b612013-03-11 22:11:519868 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]f0e6a34f2012-01-04 20:53:409869 glTexStorage2DEXT(target, levels, GetTexInternalFormat(internal_format),
9870 width, height);
[email protected]ab09b612013-03-11 22:11:519871 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:179872 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:159873 GLsizei level_width = width;
9874 GLsizei level_height = height;
9875 for (int ii = 0; ii < levels; ++ii) {
9876 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:079877 texture, target, ii, format, level_width, level_height, 1, 0, format,
[email protected]80eb6b52012-01-19 00:14:419878 type, false);
[email protected]4502e6492011-12-14 19:39:159879 level_width = std::max(1, level_width >> 1);
9880 level_height = std::max(1, level_height >> 1);
9881 }
[email protected]02965c22013-03-09 02:40:079882 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:179883 }
[email protected]97dc7cbe2011-12-06 17:26:179884}
[email protected]e51bdf32011-11-23 22:21:469885
[email protected]78b514b2012-05-01 21:50:599886error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359887 uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) {
[email protected]78b514b2012-05-01 21:50:599888 MailboxName name;
9889 mailbox_manager()->GenerateMailboxName(&name);
9890 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
9891 Bucket* bucket = CreateBucket(bucket_id);
9892
9893 bucket->SetSize(GL_MAILBOX_SIZE_CHROMIUM);
9894 bucket->SetData(&name, 0, GL_MAILBOX_SIZE_CHROMIUM);
9895
9896 return error::kNoError;
9897}
9898
9899void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
9900 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:029901 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:329902 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:029903 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
9904
[email protected]02965c22013-03-09 02:40:079905 Texture* texture = GetTextureInfoForTarget(target);
9906 if (!texture) {
[email protected]ab09b612013-03-11 22:11:519907 LOCAL_SET_GL_ERROR(
9908 GL_INVALID_OPERATION,
9909 "glProduceTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599910 return;
9911 }
9912
[email protected]02965c22013-03-09 02:40:079913 TextureDefinition* definition = texture_manager()->Save(texture);
[email protected]78b514b2012-05-01 21:50:599914 if (!definition) {
[email protected]ab09b612013-03-11 22:11:519915 LOCAL_SET_GL_ERROR(
9916 GL_INVALID_OPERATION,
9917 "glProduceTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599918 return;
9919 }
9920
9921 if (!group_->mailbox_manager()->ProduceTexture(
9922 target,
9923 *reinterpret_cast<const MailboxName*>(mailbox),
9924 definition,
9925 texture_manager())) {
[email protected]02965c22013-03-09 02:40:079926 bool success = texture_manager()->Restore(
9927 "glProductTextureCHROMIUM", this, texture, definition);
[email protected]78b514b2012-05-01 21:50:599928 DCHECK(success);
[email protected]ab09b612013-03-11 22:11:519929 LOCAL_SET_GL_ERROR(
9930 GL_INVALID_OPERATION,
9931 "glProduceTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599932 return;
9933 }
9934
[email protected]02965c22013-03-09 02:40:079935 glBindTexture(texture->target(), texture->service_id());
[email protected]78b514b2012-05-01 21:50:599936}
9937
9938void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
9939 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:029940 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:329941 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:029942 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
9943
[email protected]02965c22013-03-09 02:40:079944 Texture* texture = GetTextureInfoForTarget(target);
9945 if (!texture) {
[email protected]ab09b612013-03-11 22:11:519946 LOCAL_SET_GL_ERROR(
9947 GL_INVALID_OPERATION,
9948 "glConsumeTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599949 return;
9950 }
9951
9952 scoped_ptr<TextureDefinition> definition(
9953 group_->mailbox_manager()->ConsumeTexture(
9954 target,
9955 *reinterpret_cast<const MailboxName*>(mailbox)));
9956 if (!definition.get()) {
[email protected]ab09b612013-03-11 22:11:519957 LOCAL_SET_GL_ERROR(
9958 GL_INVALID_OPERATION,
9959 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599960 return;
9961 }
9962
[email protected]02965c22013-03-09 02:40:079963 if (!texture_manager()->Restore(
9964 "glConsumeTextureCHROMIUM", this, texture, definition.release())) {
[email protected]ab09b612013-03-11 22:11:519965 LOCAL_SET_GL_ERROR(
9966 GL_INVALID_OPERATION,
9967 "glConsumeTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599968 return;
9969 }
[email protected]78b514b2012-05-01 21:50:599970}
9971
[email protected]d2a0e1a2012-08-12 02:25:019972void GLES2DecoderImpl::DoInsertEventMarkerEXT(
9973 GLsizei length, const GLchar* marker) {
9974 if (!marker) {
9975 marker = "";
9976 }
9977 debug_marker_manager_.SetMarker(
9978 length ? std::string(marker, length) : std::string(marker));
9979}
9980
9981void GLES2DecoderImpl::DoPushGroupMarkerEXT(
9982 GLsizei length, const GLchar* marker) {
9983 if (!marker) {
9984 marker = "";
9985 }
9986 debug_marker_manager_.PushGroup(
9987 length ? std::string(marker, length) : std::string(marker));
9988}
9989
9990void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
9991 debug_marker_manager_.PopGroup();
9992}
9993
[email protected]09d50362012-10-18 20:54:379994void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
9995 GLenum target, GLint image_id) {
9996 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
9997 if (target != GL_TEXTURE_2D) {
9998 // This might be supported in the future.
[email protected]ab09b612013-03-11 22:11:519999 LOCAL_SET_GL_ERROR(
[email protected]09d50362012-10-18 20:54:3710000 GL_INVALID_OPERATION,
10001 "glBindTexImage2DCHROMIUM", "requires TEXTURE_2D target");
10002 return;
10003 }
10004
10005 // Default target might be conceptually valid, but disallow it to avoid
10006 // accidents.
[email protected]02965c22013-03-09 02:40:0710007 Texture* texture = GetTextureInfoForTargetUnlessDefault(target);
10008 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110009 LOCAL_SET_GL_ERROR(
10010 GL_INVALID_OPERATION,
10011 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710012 return;
10013 }
10014
10015 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10016 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110017 LOCAL_SET_GL_ERROR(
10018 GL_INVALID_OPERATION,
10019 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710020 return;
10021 }
10022
[email protected]b8160812013-04-09 00:41:0410023 {
10024 ScopedGLErrorSuppressor suppressor(
10025 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", this);
10026 if (!gl_image->BindTexImage()) {
10027 LOCAL_SET_GL_ERROR(
10028 GL_INVALID_OPERATION,
10029 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
10030 return;
10031 }
[email protected]09d50362012-10-18 20:54:3710032 }
10033
10034 gfx::Size size = gl_image->GetSize();
10035 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:0710036 texture, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3710037 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]02965c22013-03-09 02:40:0710038 texture_manager()->SetLevelImage(texture, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3710039}
10040
10041void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10042 GLenum target, GLint image_id) {
10043 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
10044 if (target != GL_TEXTURE_2D) {
10045 // This might be supported in the future.
[email protected]ab09b612013-03-11 22:11:5110046 LOCAL_SET_GL_ERROR(
[email protected]09d50362012-10-18 20:54:3710047 GL_INVALID_OPERATION,
10048 "glReleaseTexImage2DCHROMIUM", "requires TEXTURE_2D target");
10049 return;
10050 }
10051
10052 // Default target might be conceptually valid, but disallow it to avoid
10053 // accidents.
[email protected]02965c22013-03-09 02:40:0710054 Texture* texture = GetTextureInfoForTargetUnlessDefault(target);
10055 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110056 LOCAL_SET_GL_ERROR(
10057 GL_INVALID_OPERATION,
10058 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710059 return;
10060 }
10061
10062 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10063 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110064 LOCAL_SET_GL_ERROR(
10065 GL_INVALID_OPERATION,
10066 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710067 return;
10068 }
10069
10070 // Do nothing when image is not currently bound.
[email protected]02965c22013-03-09 02:40:0710071 if (texture->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3710072 return;
10073
[email protected]b8160812013-04-09 00:41:0410074 {
10075 ScopedGLErrorSuppressor suppressor(
10076 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", this);
10077 gl_image->ReleaseTexImage();
10078 }
[email protected]09d50362012-10-18 20:54:3710079
10080 texture_manager()->SetLevelInfo(
[email protected]02965c22013-03-09 02:40:0710081 texture, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3710082 GL_RGBA, GL_UNSIGNED_BYTE, false);
10083}
[email protected]d2a0e1a2012-08-12 02:25:0110084
[email protected]94307712012-11-16 23:26:1110085error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510086 uint32 immediate_data_size, const cmds::TraceBeginCHROMIUM& c) {
[email protected]94307712012-11-16 23:26:1110087 Bucket* bucket = GetBucket(c.bucket_id);
10088 if (!bucket || bucket->size() == 0) {
10089 return error::kInvalidArguments;
10090 }
10091 std::string command_name;
10092 if (!bucket->GetAsString(&command_name)) {
10093 return error::kInvalidArguments;
10094 }
[email protected]fb97b662013-02-20 23:02:1410095 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
10096 if (!gpu_tracer_->Begin(command_name)) {
[email protected]ab09b612013-03-11 22:11:5110097 LOCAL_SET_GL_ERROR(
10098 GL_INVALID_OPERATION,
10099 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1410100 return error::kNoError;
10101 }
[email protected]94307712012-11-16 23:26:1110102 return error::kNoError;
10103}
10104
10105void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1410106 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5110107 LOCAL_SET_GL_ERROR(
10108 GL_INVALID_OPERATION,
10109 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1110110 return;
10111 }
[email protected]fb97b662013-02-20 23:02:1410112 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
10113 gpu_tracer_->End();
[email protected]94307712012-11-16 23:26:1110114}
10115
[email protected]2f143d482013-03-14 18:04:4910116void GLES2DecoderImpl::DoDrawBuffersEXT(
10117 GLsizei count, const GLenum* bufs) {
10118 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10119 LOCAL_SET_GL_ERROR(
10120 GL_INVALID_VALUE,
10121 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10122 return;
10123 }
10124
10125 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10126 if (framebuffer) {
10127 for (GLsizei i = 0; i < count; ++i) {
10128 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10129 bufs[i] != GL_NONE) {
10130 LOCAL_SET_GL_ERROR(
10131 GL_INVALID_OPERATION,
10132 "glDrawBuffersEXT",
10133 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10134 return;
10135 }
10136 }
10137 glDrawBuffersARB(count, bufs);
10138 framebuffer->SetDrawBuffers(count, bufs);
10139 } else { // backbuffer
10140 if (count > 1 ||
10141 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10142 LOCAL_SET_GL_ERROR(
10143 GL_INVALID_OPERATION,
10144 "glDrawBuffersEXT",
10145 "more than one buffer or bufs not GL_NONE or GL_BACK");
10146 return;
10147 }
10148 GLenum mapped_buf = bufs[0];
10149 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10150 bufs[0] == GL_BACK) {
10151 mapped_buf = GL_COLOR_ATTACHMENT0;
10152 }
10153 glDrawBuffersARB(count, &mapped_buf);
10154 group_->set_draw_buffer(bufs[0]);
10155 }
10156}
10157
[email protected]32145a92012-12-17 09:01:5910158bool GLES2DecoderImpl::ValidateAsyncTransfer(
10159 const char* function_name,
[email protected]02965c22013-03-09 02:40:0710160 Texture* texture,
[email protected]32145a92012-12-17 09:01:5910161 GLenum target,
10162 GLint level,
10163 const void * data) {
10164 // We only support async uploads to 2D textures for now.
10165 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110166 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910167 return false;
10168 }
10169 // We only support uploads to level zero for now.
10170 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110171 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910172 return false;
10173 }
10174 // A transfer buffer must be bound, even for asyncTexImage2D.
10175 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110176 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910177 return false;
10178 }
10179 // We only support one async transfer in progress.
[email protected]02965c22013-03-09 02:40:0710180 if (!texture || texture->AsyncTransferIsInProgress()) {
[email protected]ab09b612013-03-11 22:11:5110181 LOCAL_SET_GL_ERROR(
10182 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910183 function_name, "transfer already in progress");
10184 return false;
10185 }
10186 return true;
10187}
10188
[email protected]69023942012-11-30 19:57:1610189error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510190 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610191 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610192 GLenum target = static_cast<GLenum>(c.target);
10193 GLint level = static_cast<GLint>(c.level);
10194 GLint internal_format = static_cast<GLint>(c.internalformat);
10195 GLsizei width = static_cast<GLsizei>(c.width);
10196 GLsizei height = static_cast<GLsizei>(c.height);
10197 GLint border = static_cast<GLint>(c.border);
10198 GLenum format = static_cast<GLenum>(c.format);
10199 GLenum type = static_cast<GLenum>(c.type);
10200 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10201 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10202 uint32 pixels_size;
[email protected]32145a92012-12-17 09:01:5910203
10204 // TODO(epenner): Move this and copies of this memory validation
10205 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1610206 if (!GLES2Util::ComputeImageDataSizes(
10207 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
10208 NULL)) {
10209 return error::kOutOfBounds;
10210 }
10211 const void* pixels = NULL;
10212 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
10213 pixels = GetSharedMemoryAs<const void*>(
10214 pixels_shm_id, pixels_shm_offset, pixels_size);
10215 if (!pixels) {
10216 return error::kOutOfBounds;
10217 }
10218 }
10219
[email protected]32145a92012-12-17 09:01:5910220 // All the normal glTexSubImage2D validation.
10221 if (!ValidateTexImage2D(
10222 "glAsyncTexImage2DCHROMIUM", target, level, internal_format,
10223 width, height, border, format, type, pixels, pixels_size)) {
10224 return error::kNoError;
10225 }
10226
10227 // Extra async validation.
[email protected]02965c22013-03-09 02:40:0710228 Texture* texture = GetTextureInfoForTarget(target);
[email protected]32145a92012-12-17 09:01:5910229 if (!ValidateAsyncTransfer(
[email protected]02965c22013-03-09 02:40:0710230 "glAsyncTexImage2DCHROMIUM", texture, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910231 return error::kNoError;
10232
10233 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0710234 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5110235 LOCAL_SET_GL_ERROR(
10236 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910237 "glAsyncTexImage2DCHROMIUM", "already defined");
10238 return error::kNoError;
10239 }
10240
[email protected]5b3a8e02013-03-13 05:36:4410241 // Since we don't allow async redefinition, this is the only
10242 // time the size of this texture can change while bound
10243 // as a frame-buffer.
10244 if (texture->IsAttachedToFramebuffer()) {
10245 // TODO(gman): If textures tracked which framebuffers they were attached to
10246 // we could just mark those framebuffers as not complete.
10247 framebuffer_manager()->IncFramebufferStateChangeCount();
10248 }
10249
[email protected]7989c9e2013-01-23 06:39:2610250 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5110251 LOCAL_SET_GL_ERROR(
10252 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610253 return error::kNoError;
10254 }
10255
[email protected]32145a92012-12-17 09:01:5910256 // We know the memory/size is safe, so get the real shared memory since
10257 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110258 gpu::Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
[email protected]32145a92012-12-17 09:01:5910259 base::SharedMemory* shared_memory = buffer.shared_memory;
10260 uint32 shm_size = buffer.size;
10261 uint32 shm_data_offset = c.pixels_shm_offset;
10262 uint32 shm_data_size = pixels_size;
10263
[email protected]5b3a8e02013-03-13 05:36:4410264 // Setup the parameters.
[email protected]32145a92012-12-17 09:01:5910265 GLenum gl_internal_format =
10266 GetTexInternalFormat(internal_format, format, type);
10267 gfx::AsyncTexImage2DParams tex_params = {target, level, gl_internal_format,
10268 width, height, border, format, type};
10269 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size,
10270 shm_data_offset, shm_data_size};
10271
[email protected]5b3a8e02013-03-13 05:36:4410272 // Set up the async state if needed, and make the texture
10273 // immutable so the async state stays valid. The level info
10274 // is set up lazily when the transfer completes.
10275 DCHECK(!texture->GetAsyncTransferState());
10276 texture->SetAsyncTransferState(
10277 async_pixel_transfer_delegate_->
10278 CreatePixelTransferState(texture->service_id(),
10279 tex_params));
10280 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5910281
10282 async_pixel_transfer_delegate_->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4410283 texture->GetAsyncTransferState(),
10284 tex_params,
10285 mem_params,
10286 base::Bind(&TextureManager::SetLevelInfoFromParams,
10287 // The callback is only invoked if the transfer state
10288 // still exists, which implies through manager->info->state
10289 // ownership that both of these pointers are valid.
10290 base::Unretained(texture_manager()),
10291 base::Unretained(texture),
10292 tex_params));
[email protected]f598f422012-12-07 08:30:0310293 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610294}
10295
10296error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510297 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610298 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610299 GLenum target = static_cast<GLenum>(c.target);
10300 GLint level = static_cast<GLint>(c.level);
10301 GLint xoffset = static_cast<GLint>(c.xoffset);
10302 GLint yoffset = static_cast<GLint>(c.yoffset);
10303 GLsizei width = static_cast<GLsizei>(c.width);
10304 GLsizei height = static_cast<GLsizei>(c.height);
10305 GLenum format = static_cast<GLenum>(c.format);
10306 GLenum type = static_cast<GLenum>(c.type);
[email protected]32145a92012-12-17 09:01:5910307
10308 // TODO(epenner): Move this and copies of this memory validation
10309 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1610310 uint32 data_size;
10311 if (!GLES2Util::ComputeImageDataSizes(
10312 width, height, format, type, state_.unpack_alignment, &data_size,
10313 NULL, NULL)) {
10314 return error::kOutOfBounds;
10315 }
10316 const void* pixels = GetSharedMemoryAs<const void*>(
10317 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5910318
10319 // All the normal glTexSubImage2D validation.
10320 error::Error error = error::kNoError;
10321 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
10322 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
10323 return error;
[email protected]69023942012-11-30 19:57:1610324 }
10325
[email protected]32145a92012-12-17 09:01:5910326 // Extra async validation.
[email protected]02965c22013-03-09 02:40:0710327 Texture* texture = GetTextureInfoForTarget(target);
[email protected]32145a92012-12-17 09:01:5910328 if (!ValidateAsyncTransfer(
[email protected]02965c22013-03-09 02:40:0710329 "glAsyncTexSubImage2DCHROMIUM", texture, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910330 return error::kNoError;
10331
10332 // Guarantee async textures are always 'cleared' as follows:
10333 // - AsyncTexImage2D can not redefine an existing texture
10334 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
10335 // - AsyncTexSubImage2D clears synchronously if not already cleared.
10336 // - Textures become immutable after an async call.
10337 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0710338 if (!texture->SafeToRenderFrom()) {
10339 if (!texture_manager()->ClearTextureLevel(this, texture, target, level)) {
[email protected]ab09b612013-03-11 22:11:5110340 LOCAL_SET_GL_ERROR(
10341 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2510342 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5910343 return error::kNoError;
10344 }
10345 }
10346
10347 // We know the memory/size is safe, so get the real shared memory since
10348 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110349 gpu::Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
[email protected]32145a92012-12-17 09:01:5910350 base::SharedMemory* shared_memory = buffer.shared_memory;
10351 uint32 shm_size = buffer.size;
10352 uint32 shm_data_offset = c.data_shm_offset;
10353 uint32 shm_data_size = data_size;
10354
[email protected]5b3a8e02013-03-13 05:36:4410355 // Setup the parameters.
[email protected]32145a92012-12-17 09:01:5910356 gfx::AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
10357 width, height, format, type};
10358 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size,
10359 shm_data_offset, shm_data_size};
[email protected]5b3a8e02013-03-13 05:36:4410360 if (!texture->GetAsyncTransferState()) {
10361 // TODO(epenner): We may want to enforce exclusive use
10362 // of async APIs in which case this should become an error,
10363 // (the texture should have been async defined).
10364 gfx::AsyncTexImage2DParams define_params = {target, level,
10365 0, 0, 0, 0, 0, 0};
10366 texture->GetLevelSize(target, level, &define_params.width,
10367 &define_params.height);
10368 texture->GetLevelType(target, level, &define_params.type,
10369 &define_params.internal_format);
10370 // Set up the async state if needed, and make the texture
10371 // immutable so the async state stays valid.
10372 texture->SetAsyncTransferState(
10373 async_pixel_transfer_delegate_->
10374 CreatePixelTransferState(texture->service_id(),
10375 define_params));
10376 texture->SetImmutable(true);
10377 }
10378
[email protected]32145a92012-12-17 09:01:5910379 async_pixel_transfer_delegate_->AsyncTexSubImage2D(
[email protected]02965c22013-03-09 02:40:0710380 texture->GetAsyncTransferState(), tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5910381 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610382}
10383
[email protected]a00c1f742013-03-05 17:02:1610384error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
10385 uint32 immediate_data_size, const cmds::WaitAsyncTexImage2DCHROMIUM& c) {
10386 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10387 GLenum target = static_cast<GLenum>(c.target);
10388
10389 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110390 LOCAL_SET_GL_ERROR(
10391 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1610392 return error::kNoError;
10393 }
[email protected]02965c22013-03-09 02:40:0710394 Texture* texture = GetTextureInfoForTarget(target);
10395 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110396 LOCAL_SET_GL_ERROR(
10397 GL_INVALID_OPERATION,
10398 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1610399 return error::kNoError;
10400 }
10401 async_pixel_transfer_delegate_->WaitForTransferCompletion(
[email protected]02965c22013-03-09 02:40:0710402 texture->GetAsyncTransferState());
[email protected]69a8701e2013-03-07 21:31:0910403 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1610404 return error::kNoError;
10405}
10406
[email protected]96449d2c2009-11-25 00:01:3210407// Include the auto-generated part of this file. We split this because it means
10408// we can easily edit the non-auto generated parts right here in this file
10409// instead of having to edit some template or the code generator.
10410#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
10411
10412} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2510413} // namespace gpu