blob: d7665f99e7e17b6e0c1c1e8d64bbfd68e2bfbfb2 [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]2a7568a2013-05-09 23:12:0359#include "gpu/command_buffer/service/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]297ca1c2011-06-20 23:08:46247// Wrapper for glEnable/glDisable that doesn't suck.
248static void EnableDisable(GLenum pname, bool enable) {
249 if (enable) {
250 glEnable(pname);
251 } else {
252 glDisable(pname);
253 }
254}
255
[email protected]6217d392010-03-25 22:08:35256// This class prevents any GL errors that occur when it is in scope from
257// being reported to the client.
258class ScopedGLErrorSuppressor {
259 public:
[email protected]ab09b612013-03-11 22:11:51260 explicit ScopedGLErrorSuppressor(
261 const char* function_name, GLES2DecoderImpl* decoder);
[email protected]6217d392010-03-25 22:08:35262 ~ScopedGLErrorSuppressor();
263 private:
[email protected]ab09b612013-03-11 22:11:51264 const char* function_name_;
[email protected]6217d392010-03-25 22:08:35265 GLES2DecoderImpl* decoder_;
266 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
267};
268
269// Temporarily changes a decoder's bound 2D texture and restore it when this
270// object goes out of scope. Also temporarily switches to using active texture
271// unit zero in case the client has changed that to something invalid.
272class ScopedTexture2DBinder {
273 public:
274 ScopedTexture2DBinder(GLES2DecoderImpl* decoder, GLuint id);
275 ~ScopedTexture2DBinder();
276
277 private:
278 GLES2DecoderImpl* decoder_;
279 DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder);
280};
281
282// Temporarily changes a decoder's bound render buffer and restore it when this
283// object goes out of scope.
284class ScopedRenderBufferBinder {
285 public:
286 ScopedRenderBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
287 ~ScopedRenderBufferBinder();
288
289 private:
290 GLES2DecoderImpl* decoder_;
291 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
292};
293
294// Temporarily changes a decoder's bound frame buffer and restore it when this
295// object goes out of scope.
296class ScopedFrameBufferBinder {
297 public:
298 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
299 ~ScopedFrameBufferBinder();
300
301 private:
302 GLES2DecoderImpl* decoder_;
303 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
304};
305
[email protected]34ff8b0c2010-10-01 20:06:02306// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52307// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27308// if it is bound or enforce_internal_framebuffer is true. If internal is
309// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02310class ScopedResolvedFrameBufferBinder {
311 public:
[email protected]e7e38032011-07-26 17:25:25312 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
[email protected]de26b3c2011-08-03 21:54:27313 bool enforce_internal_framebuffer,
314 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02315 ~ScopedResolvedFrameBufferBinder();
316
317 private:
318 GLES2DecoderImpl* decoder_;
319 bool resolve_and_bind_;
320 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
321};
322
[email protected]63b465922012-09-06 02:04:52323// This class records texture upload time when in scope.
324class ScopedTextureUploadTimer {
325 public:
326 explicit ScopedTextureUploadTimer(GLES2DecoderImpl* decoder);
327 ~ScopedTextureUploadTimer();
328
329 private:
330 GLES2DecoderImpl* decoder_;
331 base::TimeTicks begin_time_;
332 DISALLOW_COPY_AND_ASSIGN(ScopedTextureUploadTimer);
333};
334
[email protected]6217d392010-03-25 22:08:35335// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35336class BackTexture {
[email protected]6217d392010-03-25 22:08:35337 public:
[email protected]ed9f9cd2013-02-27 21:12:35338 explicit BackTexture(GLES2DecoderImpl* decoder);
339 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35340
341 // Create a new render texture.
342 void Create();
343
344 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09345 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35346
347 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58348 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35349
350 // Destroy the render texture. This must be explicitly called before
351 // destroying this object.
352 void Destroy();
353
[email protected]97872062010-11-03 19:07:05354 // Invalidate the texture. This can be used when a context is lost and it is
355 // not possible to make it current in order to free the resource.
356 void Invalidate();
357
[email protected]6217d392010-03-25 22:08:35358 GLuint id() const {
359 return id_;
360 }
361
[email protected]d37231fa2010-04-09 21:16:02362 gfx::Size size() const {
363 return size_;
364 }
365
[email protected]1078f912011-12-23 13:12:14366 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25367 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14368 }
369
[email protected]6217d392010-03-25 22:08:35370 private:
371 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25372 MemoryTypeTracker memory_tracker_;
[email protected]68e81a4a62012-12-13 01:16:48373 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35374 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02375 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35376 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35377};
378
379// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35380class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35381 public:
[email protected]ed9f9cd2013-02-27 21:12:35382 explicit BackRenderbuffer(GLES2DecoderImpl* decoder);
383 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35384
385 // Create a new render buffer.
386 void Create();
387
388 // Set the initial size and format of a render buffer or resize it.
[email protected]34ff8b0c2010-10-01 20:06:02389 bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples);
[email protected]6217d392010-03-25 22:08:35390
391 // Destroy the render buffer. This must be explicitly called before destroying
392 // this object.
393 void Destroy();
394
[email protected]97872062010-11-03 19:07:05395 // Invalidate the render buffer. This can be used when a context is lost and
396 // it is not possible to make it current in order to free the resource.
397 void Invalidate();
398
[email protected]6217d392010-03-25 22:08:35399 GLuint id() const {
400 return id_;
401 }
402
[email protected]1078f912011-12-23 13:12:14403 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25404 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14405 }
406
[email protected]6217d392010-03-25 22:08:35407 private:
408 GLES2DecoderImpl* decoder_;
[email protected]ff6493f2012-07-31 19:52:25409 MemoryTypeTracker memory_tracker_;
[email protected]68e81a4a62012-12-13 01:16:48410 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35411 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35412 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35413};
414
415// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35416class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35417 public:
[email protected]ed9f9cd2013-02-27 21:12:35418 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
419 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35420
421 // Create a new frame buffer.
422 void Create();
423
424 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35425 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35426
[email protected]b9363b22010-06-09 22:06:15427 // Attach a render buffer to a frame buffer. Note that this unbinds any
428 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35429 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35430
[email protected]6217d392010-03-25 22:08:35431 // Destroy the frame buffer. This must be explicitly called before destroying
432 // this object.
433 void Destroy();
434
[email protected]97872062010-11-03 19:07:05435 // Invalidate the frame buffer. This can be used when a context is lost and it
436 // is not possible to make it current in order to free the resource.
437 void Invalidate();
438
[email protected]6217d392010-03-25 22:08:35439 // See glCheckFramebufferStatusEXT.
440 GLenum CheckStatus();
441
442 GLuint id() const {
443 return id_;
444 }
445
446 private:
447 GLES2DecoderImpl* decoder_;
448 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35449 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35450};
[email protected]34ff8b0c2010-10-01 20:06:02451
[email protected]43f28f832010-02-03 02:28:48452// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32453
[email protected]ddb1e5a2010-12-13 20:10:45454bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
455 uint32* service_texture_id) {
456 return false;
457}
458
[email protected]a3ded6d2010-10-19 06:44:39459GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06460 : initialized_(false),
461 debug_(false),
[email protected]1d82e822013-04-10 21:32:32462 log_commands_(false) {
[email protected]96449d2c2009-11-25 00:01:32463}
464
[email protected]3916c97e2010-02-25 03:20:50465GLES2Decoder::~GLES2Decoder() {
466}
467
[email protected]57edfdad2012-02-07 04:57:15468bool GLES2Decoder::testing_force_is_angle_;
469
470void GLES2Decoder::set_testing_force_is_angle(bool force) {
471 testing_force_is_angle_ = force;
472}
473
474bool GLES2Decoder::IsAngle() {
475#if defined(OS_WIN)
476 return testing_force_is_angle_ ||
477 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2;
478#else
479 return testing_force_is_angle_;
480#endif
481}
482
[email protected]f39f4b3f2010-05-12 17:04:08483// This class implements GLES2Decoder so we don't have to expose all the GLES2
484// cmd stuff to outside this class.
[email protected]ee1e6aa2012-11-29 09:24:10485class GLES2DecoderImpl : public GLES2Decoder {
[email protected]f39f4b3f2010-05-12 17:04:08486 public:
[email protected]476ccb72012-12-06 15:52:52487 // Used by PrepForSetUniformByLocation to validate types.
488 struct BaseUniformInfo {
489 const GLenum* const valid_types;
490 size_t num_valid_types;
491 };
492
[email protected]aa7666122011-09-02 19:45:52493 explicit GLES2DecoderImpl(ContextGroup* group);
[email protected]b8e97b62012-09-30 15:09:00494 virtual ~GLES2DecoderImpl();
[email protected]f39f4b3f2010-05-12 17:04:08495
[email protected]96449d2c2009-11-25 00:01:32496 // Overridden from AsyncAPIInterface.
[email protected]f7a64ee2010-02-01 22:24:14497 virtual Error DoCommand(unsigned int command,
[email protected]3916c97e2010-02-25 03:20:50498 unsigned int arg_count,
[email protected]b8e97b62012-09-30 15:09:00499 const void* args) OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32500
501 // Overridden from AsyncAPIInterface.
[email protected]b8e97b62012-09-30 15:09:00502 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32503
504 // Overridden from GLES2Decoder.
[email protected]fbe20372011-06-01 01:46:38505 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
506 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:23507 bool offscreen,
[email protected]6217d392010-03-25 22:08:35508 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29509 const DisallowedFeatures& disallowed_features,
[email protected]a3ded6d2010-10-19 06:44:39510 const char* allowed_extensions,
[email protected]b8e97b62012-09-30 15:09:00511 const std::vector<int32>& attribs) OVERRIDE;
512 virtual void Destroy(bool have_context) OVERRIDE;
[email protected]63c9b052012-05-17 18:27:38513 virtual void SetSurface(
514 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
[email protected]3c644d82011-06-20 19:58:24515 virtual bool SetParent(GLES2Decoder* parent_decoder,
[email protected]b8e97b62012-09-30 15:09:00516 uint32 parent_texture_id) OVERRIDE;
517 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
[email protected]9a5afa432011-07-22 18:16:39518 void UpdateParentTextureInfo();
[email protected]b8e97b62012-09-30 15:09:00519 virtual bool MakeCurrent() OVERRIDE;
520 virtual void ReleaseCurrent() OVERRIDE;
521 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
522 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
523 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
[email protected]1868a342012-11-07 15:56:02524 virtual void RestoreState() const OVERRIDE;
[email protected]29a4d902013-02-26 20:18:06525
526 virtual void RestoreActiveTexture() const OVERRIDE {
527 state_.RestoreActiveTexture();
528 }
[email protected]217004512013-05-10 21:25:55529 virtual void RestoreAllTextureUnitBindings() const OVERRIDE {
530 state_.RestoreAllTextureUnitBindings();
531 }
[email protected]29a4d902013-02-26 20:18:06532 virtual void RestoreAttribute(unsigned index) const OVERRIDE {
533 state_.RestoreAttribute(index);
534 }
535 virtual void RestoreBufferBindings() const OVERRIDE {
536 state_.RestoreBufferBindings();
537 }
538 virtual void RestoreGlobalState() const OVERRIDE {
539 state_.RestoreGlobalState();
540 }
541 virtual void RestoreProgramBindings() const OVERRIDE {
542 state_.RestoreProgramBindings();
543 }
544 virtual void RestoreRenderbufferBindings() const OVERRIDE {
545 state_.RestoreRenderbufferBindings();
546 }
547 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE {
548 state_.RestoreTextureUnitBindings(unit);
549 }
550 virtual void RestoreFramebufferBindings() const OVERRIDE;
551 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE;
552
[email protected]b8e97b62012-09-30 15:09:00553 virtual QueryManager* GetQueryManager() OVERRIDE {
554 return query_manager_.get();
555 }
556 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
[email protected]944b62f32012-09-27 02:20:46557 return vertex_array_manager_.get();
558 }
[email protected]b8e97b62012-09-30 15:09:00559 virtual bool ProcessPendingQueries() OVERRIDE;
[email protected]2b1767cf2013-03-16 09:25:05560 virtual bool HasMoreIdleWork() OVERRIDE;
561 virtual void PerformIdleWork() OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48562
[email protected]9d37f062011-11-22 01:24:52563 virtual void SetResizeCallback(
[email protected]b8e97b62012-09-30 15:09:00564 const base::Callback<void(gfx::Size)>& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00565
[email protected]1d82e822013-04-10 21:32:32566 virtual Logger* GetLogger() OVERRIDE;
[email protected]d3eba342013-04-18 21:11:50567 virtual ErrorState* GetErrorState() OVERRIDE;
[email protected]1d82e822013-04-10 21:32:32568
[email protected]e3932abb2013-03-13 00:01:37569 virtual void SetShaderCacheCallback(
570 const ShaderCacheCallback& callback) OVERRIDE;
[email protected]840a7e462013-02-27 01:29:51571 virtual void SetWaitSyncPointCallback(
572 const WaitSyncPointCallback& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00573
[email protected]b8e97b62012-09-30 15:09:00574 virtual void SetStreamTextureManager(StreamTextureManager* manager) OVERRIDE;
[email protected]32145a92012-12-17 09:01:59575
[email protected]2a7568a2013-05-09 23:12:03576 virtual AsyncPixelTransferDelegate*
[email protected]32145a92012-12-17 09:01:59577 GetAsyncPixelTransferDelegate() OVERRIDE;
578 virtual void SetAsyncPixelTransferDelegate(
[email protected]2a7568a2013-05-09 23:12:03579 AsyncPixelTransferDelegate* delegate) OVERRIDE;
[email protected]69a8701e2013-03-07 21:31:09580 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59581
[email protected]1318e922010-09-17 22:03:16582 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00583 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48584
[email protected]63b465922012-09-06 02:04:52585 virtual uint32 GetTextureUploadCount() OVERRIDE;
586 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
587 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30588 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52589
[email protected]8e3e0662010-08-23 18:46:30590 // Restores the current state to the user's settings.
591 void RestoreCurrentFramebufferBindings();
592 void RestoreCurrentRenderbufferBindings();
593 void RestoreCurrentTexture2DBindings();
594
[email protected]297ca1c2011-06-20 23:08:46595 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
596 void ApplyDirtyState();
597
598 // These check the state of the currently bound framebuffer or the
599 // backbuffer if no framebuffer is bound.
600 bool BoundFramebufferHasColorAttachmentWithAlpha();
601 bool BoundFramebufferHasDepthAttachment();
602 bool BoundFramebufferHasStencilAttachment();
603
[email protected]b8e97b62012-09-30 15:09:00604 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43605
[email protected]96449d2c2009-11-25 00:01:32606 private:
[email protected]70d34263c2013-01-09 00:27:45607 friend class ScopedFrameBufferBinder;
[email protected]6217d392010-03-25 22:08:35608 friend class ScopedGLErrorSuppressor;
[email protected]34ff8b0c2010-10-01 20:06:02609 friend class ScopedResolvedFrameBufferBinder;
[email protected]63b465922012-09-06 02:04:52610 friend class ScopedTextureUploadTimer;
[email protected]ed9f9cd2013-02-27 21:12:35611 friend class BackTexture;
612 friend class BackRenderbuffer;
613 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35614
[email protected]c2f8c8402010-12-06 18:07:24615 // Initialize or re-initialize the shader translator.
616 bool InitializeShaderTranslator();
617
[email protected]302ce6d2011-07-07 23:28:11618 void UpdateCapabilities();
619
[email protected]ae51d192010-04-27 00:48:03620 // Helpers for the glGen and glDelete functions.
621 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
622 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
623 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
624 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
625 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
626 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
627 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
628 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53629 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
630 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46631 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
632 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47633
[email protected]70d34263c2013-01-09 00:27:45634 // Workarounds
635 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51636 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45637
[email protected]3916c97e2010-02-25 03:20:50638 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50639 BufferManager* buffer_manager() {
640 return group_->buffer_manager();
641 }
642
[email protected]a25fa872010-03-25 02:57:58643 RenderbufferManager* renderbuffer_manager() {
644 return group_->renderbuffer_manager();
645 }
646
647 FramebufferManager* framebuffer_manager() {
648 return group_->framebuffer_manager();
649 }
650
[email protected]3916c97e2010-02-25 03:20:50651 ProgramManager* program_manager() {
652 return group_->program_manager();
653 }
654
655 ShaderManager* shader_manager() {
656 return group_->shader_manager();
657 }
658
[email protected]29a4d902013-02-26 20:18:06659 const TextureManager* texture_manager() const {
660 return group_->texture_manager();
661 }
662
[email protected]3916c97e2010-02-25 03:20:50663 TextureManager* texture_manager() {
664 return group_->texture_manager();
665 }
666
[email protected]78b514b2012-05-01 21:50:59667 MailboxManager* mailbox_manager() {
668 return group_->mailbox_manager();
669 }
670
[email protected]09d50362012-10-18 20:54:37671 ImageManager* image_manager() {
672 return group_->image_manager();
673 }
674
[email protected]944b62f32012-09-27 02:20:46675 VertexArrayManager* vertex_array_manager() {
676 return vertex_array_manager_.get();
677 }
678
[email protected]7989c9e2013-01-23 06:39:26679 MemoryTracker* memory_tracker() {
680 return group_->memory_tracker();
681 }
682
683 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
684 MemoryTracker* tracker = memory_tracker();
685 if (tracker) {
686 return tracker->EnsureGPUMemoryAvailable(estimated_size);
687 }
688 return true;
689 }
690
[email protected]34ff8b0c2010-10-01 20:06:02691 bool IsOffscreenBufferMultisampled() const {
692 return offscreen_target_samples_ > 1;
693 }
694
[email protected]ed9f9cd2013-02-27 21:12:35695 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49696 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03697 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35698 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47699 }
700
701 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49702 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07703 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47704 }
705
706 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35707 void RemoveTexture(GLuint client_id) {
708 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50709 }
[email protected]a93bb842010-02-16 23:03:47710
[email protected]d37231fa2010-04-09 21:16:02711 // Get the size (in pixels) of the currently bound frame buffer (either FBO
712 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30713 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02714
[email protected]9edc6b22010-12-23 02:00:26715 // Get the format of the currently bound frame buffer (either FBO or regular
716 // back buffer)
717 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46718 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26719
[email protected]a93bb842010-02-16 23:03:47720 // Wrapper for CompressedTexImage2D commands.
721 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37722 GLenum target,
723 GLint level,
724 GLenum internal_format,
725 GLsizei width,
726 GLsizei height,
727 GLint border,
728 GLsizei image_size,
729 const void* data);
[email protected]a93bb842010-02-16 23:03:47730
[email protected]cadde4a2010-07-31 17:10:43731 // Wrapper for CompressedTexSubImage2D.
732 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37733 GLenum target,
734 GLint level,
735 GLint xoffset,
736 GLint yoffset,
737 GLsizei width,
738 GLsizei height,
739 GLenum format,
740 GLsizei imageSize,
741 const void * data);
[email protected]cadde4a2010-07-31 17:10:43742
743 // Wrapper for CopyTexImage2D.
744 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37745 GLenum target,
746 GLint level,
747 GLenum internal_format,
748 GLint x,
749 GLint y,
750 GLsizei width,
751 GLsizei height,
752 GLint border);
[email protected]cadde4a2010-07-31 17:10:43753
[email protected]6d792ee12013-05-15 00:40:56754 // Wrapper for SwapBuffers.
755 void DoSwapBuffers();
756
[email protected]cadde4a2010-07-31 17:10:43757 // Wrapper for CopyTexSubImage2D.
758 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37759 GLenum target,
760 GLint level,
761 GLint xoffset,
762 GLint yoffset,
763 GLint x,
764 GLint y,
765 GLsizei width,
766 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43767
[email protected]f598f422012-12-07 08:30:03768 // Validation for TexImage2D commands.
769 bool ValidateTexImage2D(
770 const char* function_name,
[email protected]09d50362012-10-18 20:54:37771 GLenum target,
772 GLint level,
773 GLenum internal_format,
774 GLsizei width,
775 GLsizei height,
776 GLint border,
777 GLenum format,
778 GLenum type,
779 const void* pixels,
780 uint32 pixels_size);
[email protected]a93bb842010-02-16 23:03:47781
[email protected]f598f422012-12-07 08:30:03782 // Wrapper for TexImage2D commands.
783 void DoTexImage2D(
784 GLenum target,
785 GLint level,
786 GLenum internal_format,
787 GLsizei width,
788 GLsizei height,
789 GLint border,
790 GLenum format,
791 GLenum type,
792 const void* pixels,
793 uint32 pixels_size);
794
795 // Validation for TexSubImage2D.
796 bool ValidateTexSubImage2D(
797 error::Error* error,
798 const char* function_name,
799 GLenum target,
800 GLint level,
801 GLint xoffset,
802 GLint yoffset,
803 GLsizei width,
804 GLsizei height,
805 GLenum format,
806 GLenum type,
807 const void * data);
808
[email protected]cadde4a2010-07-31 17:10:43809 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03810 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37811 GLenum target,
812 GLint level,
813 GLint xoffset,
814 GLint yoffset,
815 GLsizei width,
816 GLsizei height,
817 GLenum format,
818 GLenum type,
819 const void * data);
[email protected]cadde4a2010-07-31 17:10:43820
[email protected]32145a92012-12-17 09:01:59821 // Extra validation for async tex(Sub)Image2D.
822 bool ValidateAsyncTransfer(
823 const char* function_name,
[email protected]02965c22013-03-09 02:40:07824 Texture* texture,
[email protected]32145a92012-12-17 09:01:59825 GLenum target,
826 GLint level,
827 const void * data);
828
[email protected]e51bdf32011-11-23 22:21:46829 // Wrapper for TexImageIOSurface2DCHROMIUM.
830 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37831 GLenum target,
832 GLsizei width,
833 GLsizei height,
834 GLuint io_surface_id,
835 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46836
[email protected]43410e92012-04-20 17:06:28837 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37838 GLenum target,
839 GLuint source_id,
840 GLuint target_id,
841 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54842 GLenum internal_format,
843 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28844
[email protected]97dc7cbe2011-12-06 17:26:17845 // Wrapper for TexStorage2DEXT.
846 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37847 GLenum target,
848 GLint levels,
849 GLenum internal_format,
850 GLsizei width,
851 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17852
[email protected]78b514b2012-05-01 21:50:59853 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
854 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
855
[email protected]09d50362012-10-18 20:54:37856 void DoBindTexImage2DCHROMIUM(
857 GLenum target,
858 GLint image_id);
859 void DoReleaseTexImage2DCHROMIUM(
860 GLenum target,
861 GLint image_id);
862
[email protected]94307712012-11-16 23:26:11863 void DoTraceEndCHROMIUM(void);
864
[email protected]2f143d482013-03-14 18:04:49865 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
866
[email protected]ed9f9cd2013-02-27 21:12:35867 // Creates a Program for the given program.
868 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57869 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35870 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47871 }
872
[email protected]07f54fcc2009-12-22 02:46:30873 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35874 Program* GetProgram(GLuint client_id) {
875 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46876 }
[email protected]07f54fcc2009-12-22 02:46:30877
[email protected]cae20172012-12-07 00:06:19878#if defined(NDEBUG)
879 void LogClientServiceMapping(
880 const char* /* function_name */,
881 GLuint /* client_id */,
882 GLuint /* service_id */) {
883 }
884 template<typename T>
885 void LogClientServiceForInfo(
886 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
887 }
888#else
889 void LogClientServiceMapping(
890 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:26891 if (service_logging_) {
[email protected]1d82e822013-04-10 21:32:32892 DLOG(INFO) << "[" << logger_.GetLogPrefix() << "] " << function_name
[email protected]2a22fe72012-12-07 04:21:26893 << ": client_id = " << client_id
894 << ", service_id = " << service_id;
895 }
[email protected]cae20172012-12-07 00:06:19896 }
897 template<typename T>
898 void LogClientServiceForInfo(
899 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:26900 if (info) {
[email protected]cae20172012-12-07 00:06:19901 LogClientServiceMapping(function_name, client_id, info->service_id());
902 }
903 }
904#endif
905
[email protected]6b8cf1a2010-05-06 16:13:58906 // Gets the program info for the given program. If it's not a program
907 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:35908 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:58909 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42910 Program* program = GetProgram(client_id);
911 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:35912 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:51913 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43914 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:58915 } else {
[email protected]ab09b612013-03-11 22:11:51916 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:58917 }
918 }
[email protected]df37b9932013-03-08 05:21:42919 LogClientServiceForInfo(program, client_id, function_name);
920 return program;
[email protected]6b8cf1a2010-05-06 16:13:58921 }
922
923
[email protected]ed9f9cd2013-02-27 21:12:35924 // Creates a Shader for the given shader.
925 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:57926 GLuint client_id,
927 GLuint service_id,
928 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:35929 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:57930 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:31931 }
932
933 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35934 Shader* GetShader(GLuint client_id) {
935 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:31936 }
937
[email protected]6b8cf1a2010-05-06 16:13:58938 // Gets the shader info for the given shader. If it's not a shader generates a
939 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:35940 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:58941 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42942 Shader* shader = GetShader(client_id);
943 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:35944 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:51945 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43946 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:58947 } else {
[email protected]ab09b612013-03-11 22:11:51948 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43949 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:58950 }
951 }
[email protected]df37b9932013-03-08 05:21:42952 LogClientServiceForInfo(shader, client_id, function_name);
953 return shader;
[email protected]6b8cf1a2010-05-06 16:13:58954 }
955
[email protected]a93bb842010-02-16 23:03:47956 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:35957 void CreateBuffer(GLuint client_id, GLuint service_id) {
958 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47959 }
960
[email protected]07f54fcc2009-12-22 02:46:30961 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:21962 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:07963 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
964 return buffer;
[email protected]1d32bc82010-01-13 22:06:46965 }
[email protected]07f54fcc2009-12-22 02:46:30966
[email protected]a93bb842010-02-16 23:03:47967 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
968 // on glDeleteBuffers so we can make sure the user does not try to render
969 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:35970 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:47971
[email protected]a25fa872010-03-25 02:57:58972 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:35973 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
974 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:58975 }
976
977 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:06978 Framebuffer* GetFramebuffer(GLuint client_id) {
979 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:58980 }
981
982 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:35983 void RemoveFramebuffer(GLuint client_id) {
984 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:58985 }
986
987 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:35988 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
989 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:03990 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:58991 }
992
993 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:27994 Renderbuffer* GetRenderbuffer(GLuint client_id) {
995 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:58996 }
997
998 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:35999 void RemoveRenderbuffer(GLuint client_id) {
1000 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581001 }
1002
[email protected]944b62f32012-09-27 02:20:461003 // Gets the vertex attrib manager for the given vertex array.
1004 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1005 VertexAttribManager* info =
1006 vertex_array_manager()->GetVertexAttribManager(client_id);
1007 return info;
1008 }
1009
1010 // Removes the vertex attrib manager for the given vertex array.
1011 void RemoveVertexAttribManager(GLuint client_id) {
1012 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1013 }
1014
1015 // Creates a vertex attrib manager for the given vertex array.
1016 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) {
1017 return vertex_array_manager()->CreateVertexAttribManager(
1018 client_id, service_id, group_->max_vertex_attribs());
1019 }
1020
[email protected]258a3313f2011-10-18 20:13:571021 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331022 void DoBindUniformLocationCHROMIUM(
1023 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571024
[email protected]558847a2010-03-24 07:02:541025 error::Error GetAttribLocationHelper(
1026 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1027 const std::string& name_str);
1028
1029 error::Error GetUniformLocationHelper(
1030 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1031 const std::string& name_str);
1032
[email protected]3916c97e2010-02-25 03:20:501033 // Helper for glShaderSource.
1034 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031035 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301036
[email protected]0d6bfdc2011-11-02 01:32:201037 // Clear any textures used by the current program.
1038 bool ClearUnclearedTextures();
1039
1040 // Clear any uncleared level in texture.
1041 // Returns false if there was a generated GL error.
[email protected]02965c22013-03-09 02:40:071042 bool ClearTexture(Texture* texture);
[email protected]0d6bfdc2011-11-02 01:32:201043
1044 // Clears any uncleared attachments attached to the given frame buffer.
1045 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061046 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281047
[email protected]0d6bfdc2011-11-02 01:32:201048 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:001049 virtual bool ClearLevel(unsigned service_id,
1050 unsigned bind_target,
1051 unsigned target,
1052 int level,
1053 unsigned format,
1054 unsigned type,
1055 int width,
1056 int height,
1057 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:201058
[email protected]c007aa02010-09-02 22:22:401059 // Restore all GL state that affects clearing.
1060 void RestoreClearState();
1061
[email protected]3a2e7c7b2010-08-06 01:12:281062 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461063 // Returns: true if glEnable/glDisable should actually be called.
1064 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281065
[email protected]0d6bfdc2011-11-02 01:32:201066 // Check that the currently bound framebuffers are valid.
1067 // Generates GL error if not.
1068 bool CheckBoundFramebuffersValid(const char* func_name);
1069
1070 // Check if a framebuffer meets our requirements.
1071 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351072 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201073 GLenum target,
1074 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271075
[email protected]939e7362010-05-13 20:49:101076 // Checks if the current program exists and is valid. If not generates the
1077 // appropriate GL error. Returns true if the current program is in a usable
1078 // state.
1079 bool CheckCurrentProgram(const char* function_name);
1080
1081 // Checks if the current program exists and is valid and that location is not
1082 // -1. If the current program is not valid generates the appropriate GL
1083 // error. Returns true if the current program is in a usable state and
1084 // location is not -1.
1085 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1086
1087 // Gets the type of a uniform for a location in the current program. Sets GL
1088 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361089 // program is valid and the location exists. Adjusts count so it
1090 // does not overflow the uniform.
1091 bool PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:121092 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:521093 const BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:121094 GLint* real_location, GLenum* type, GLsizei* count);
[email protected]939e7362010-05-13 20:49:101095
[email protected]b177ae22011-11-01 03:29:111096 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021097 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111098
[email protected]b273e432010-04-12 17:23:581099 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1100 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1101
[email protected]ac77603c72013-03-08 13:52:061102 // Helper for glGetVertexAttrib
1103 void GetVertexAttribHelper(
1104 const VertexAttrib* attrib, GLenum pname, GLint* param);
1105
[email protected]96449d2c2009-11-25 00:01:321106 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031107 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321108
1109 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031110 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321111
[email protected]3916c97e2010-02-25 03:20:501112 // Wrapper for glActiveTexture
1113 void DoActiveTexture(GLenum texture_unit);
1114
[email protected]ae51d192010-04-27 00:48:031115 // Wrapper for glAttachShader
1116 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1117
[email protected]96449d2c2009-11-25 00:01:321118 // Wrapper for glBindBuffer since we need to track the current targets.
1119 void DoBindBuffer(GLenum target, GLuint buffer);
1120
[email protected]86093972010-03-11 00:13:561121 // Wrapper for glBindFramebuffer since we need to track the current targets.
1122 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1123
1124 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1125 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1126
[email protected]a93bb842010-02-16 23:03:471127 // Wrapper for glBindTexture since we need to track the current targets.
1128 void DoBindTexture(GLenum target, GLuint texture);
1129
[email protected]944b62f32012-09-27 02:20:461130 // Wrapper for glBindVertexArrayOES
1131 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571132 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461133
[email protected]8e3e0662010-08-23 18:46:301134 // Wrapper for glBlitFramebufferEXT.
1135 void DoBlitFramebufferEXT(
1136 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1137 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1138 GLbitfield mask, GLenum filter);
1139
[email protected]36cef8ce2010-03-16 07:34:451140 // Wrapper for glBufferData.
[email protected]0c86dbf2010-03-05 08:14:111141 void DoBufferData(
1142 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
1143
[email protected]36cef8ce2010-03-16 07:34:451144 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111145 void DoBufferSubData(
1146 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1147
[email protected]36cef8ce2010-03-16 07:34:451148 // Wrapper for glCheckFramebufferStatus
1149 GLenum DoCheckFramebufferStatus(GLenum target);
1150
[email protected]3a03a8f2011-03-19 00:51:271151 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081152 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271153
[email protected]88a61bf2012-10-27 13:00:421154 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421155 void DoDepthRangef(GLclampf znear, GLclampf zfar);
1156 void DoHint(GLenum target, GLenum mode);
[email protected]b04e24c2013-01-08 18:35:251157 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281158
[email protected]45bf5152010-02-12 00:11:311159 // Wrapper for glCompileShader.
1160 void DoCompileShader(GLuint shader);
1161
[email protected]269200b12010-11-18 22:53:061162 // Helper for DeleteSharedIdsCHROMIUM commands.
1163 void DoDeleteSharedIdsCHROMIUM(
1164 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101165
[email protected]ae51d192010-04-27 00:48:031166 // Wrapper for glDetachShader
1167 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1168
[email protected]3a2e7c7b2010-08-06 01:12:281169 // Wrapper for glDisable
1170 void DoDisable(GLenum cap);
1171
[email protected]07f54fcc2009-12-22 02:46:301172 // Wrapper for glDisableVertexAttribArray.
1173 void DoDisableVertexAttribArray(GLuint index);
1174
[email protected]60f22d32012-12-12 00:31:581175 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1176 // attachments.
1177 void DoDiscardFramebufferEXT(GLenum target,
1178 GLsizei numAttachments,
1179 const GLenum* attachments);
1180
[email protected]3a2e7c7b2010-08-06 01:12:281181 // Wrapper for glEnable
1182 void DoEnable(GLenum cap);
1183
[email protected]07f54fcc2009-12-22 02:46:301184 // Wrapper for glEnableVertexAttribArray.
1185 void DoEnableVertexAttribArray(GLuint index);
1186
[email protected]882ba1e22012-03-08 19:02:531187 // Wrapper for glFinish.
1188 void DoFinish();
1189
1190 // Wrapper for glFlush.
1191 void DoFlush();
1192
[email protected]36cef8ce2010-03-16 07:34:451193 // Wrapper for glFramebufferRenderbufffer.
1194 void DoFramebufferRenderbuffer(
1195 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1196 GLuint renderbuffer);
1197
1198 // Wrapper for glFramebufferTexture2D.
1199 void DoFramebufferTexture2D(
1200 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1201 GLint level);
1202
[email protected]a93bb842010-02-16 23:03:471203 // Wrapper for glGenerateMipmap
1204 void DoGenerateMipmap(GLenum target);
1205
[email protected]269200b12010-11-18 22:53:061206 // Helper for GenSharedIdsCHROMIUM commands.
1207 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101208 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1209
[email protected]b273e432010-04-12 17:23:581210 // Wrapper for DoGetBooleanv.
1211 void DoGetBooleanv(GLenum pname, GLboolean* params);
1212
1213 // Wrapper for DoGetFloatv.
1214 void DoGetFloatv(GLenum pname, GLfloat* params);
1215
[email protected]36cef8ce2010-03-16 07:34:451216 // Wrapper for glGetFramebufferAttachmentParameteriv.
1217 void DoGetFramebufferAttachmentParameteriv(
1218 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1219
[email protected]a0c3e972010-04-21 00:49:131220 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581221 void DoGetIntegerv(GLenum pname, GLint* params);
1222
[email protected]29a9eb52010-04-13 09:04:231223 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061224 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231225 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1226
[email protected]17cfbe0e2013-03-07 01:26:081227 // Wrapper for glGetBufferParameteriv.
1228 void DoGetBufferParameteriv(
1229 GLenum target, GLenum pname, GLint* params);
1230
[email protected]a0c3e972010-04-21 00:49:131231 // Wrapper for glGetProgramiv.
1232 void DoGetProgramiv(
1233 GLuint program_id, GLenum pname, GLint* params);
1234
[email protected]36cef8ce2010-03-16 07:34:451235 // Wrapper for glRenderbufferParameteriv.
1236 void DoGetRenderbufferParameteriv(
1237 GLenum target, GLenum pname, GLint* params);
1238
[email protected]ddd968b82010-03-02 00:44:291239 // Wrapper for glGetShaderiv
1240 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1241
[email protected]b1122982010-05-17 23:04:241242 // Wrappers for glGetVertexAttrib.
1243 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1244 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1245
[email protected]1958e0e2010-04-22 05:17:151246 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241247 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151248 bool DoIsBuffer(GLuint client_id);
1249 bool DoIsFramebuffer(GLuint client_id);
1250 bool DoIsProgram(GLuint client_id);
1251 bool DoIsRenderbuffer(GLuint client_id);
1252 bool DoIsShader(GLuint client_id);
1253 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461254 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151255
[email protected]07f54fcc2009-12-22 02:46:301256 // Wrapper for glLinkProgram
1257 void DoLinkProgram(GLuint program);
1258
[email protected]269200b12010-11-18 22:53:061259 // Helper for RegisterSharedIdsCHROMIUM.
1260 void DoRegisterSharedIdsCHROMIUM(
1261 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101262
[email protected]36cef8ce2010-03-16 07:34:451263 // Wrapper for glRenderbufferStorage.
1264 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031265 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451266
[email protected]8e3e0662010-08-23 18:46:301267 // Wrapper for glRenderbufferStorageMultisampleEXT.
1268 void DoRenderbufferStorageMultisample(
1269 GLenum target, GLsizei samples, GLenum internalformat,
1270 GLsizei width, GLsizei height);
1271
[email protected]b273e432010-04-12 17:23:581272 // Wrapper for glReleaseShaderCompiler.
1273 void DoReleaseShaderCompiler() { }
1274
[email protected]3916c97e2010-02-25 03:20:501275 // Wrappers for glTexParameter functions.
1276 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1277 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1278 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1279 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1280
1281 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1282 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121283 void DoUniform1i(GLint fake_location, GLint v0);
1284 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1285 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1286 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1287 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101288
1289 // Wrappers for glUniformfv because some drivers don't correctly accept
1290 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121291 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1292 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1293 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1294 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501295
[email protected]43c2f1f2011-03-25 18:35:361296 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121297 GLint fake_location, GLsizei count, GLboolean transpose,
1298 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361299 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121300 GLint fake_location, GLsizei count, GLboolean transpose,
1301 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361302 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121303 GLint fake_location, GLsizei count, GLboolean transpose,
1304 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361305
[email protected]af6380962012-11-29 23:24:131306 bool SetVertexAttribValue(
1307 const char* function_name, GLuint index, const GLfloat* value);
1308
[email protected]b1122982010-05-17 23:04:241309 // Wrappers for glVertexAttrib??
1310 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1311 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1312 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1313 void DoVertexAttrib4f(
1314 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1315 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1316 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1317 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1318 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1319
[email protected]43410e92012-04-20 17:06:281320 // Wrapper for glViewport
1321 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1322
[email protected]07f54fcc2009-12-22 02:46:301323 // Wrapper for glUseProgram
1324 void DoUseProgram(GLuint program);
1325
[email protected]ae51d192010-04-27 00:48:031326 // Wrapper for glValidateProgram.
1327 void DoValidateProgram(GLuint program_client_id);
1328
[email protected]d2a0e1a2012-08-12 02:25:011329 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1330 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1331 void DoPopGroupMarkerEXT(void);
1332
[email protected]4e8a5b122010-05-08 22:00:101333 // Gets the number of values that will be returned by glGetXXX. Returns
1334 // false if pname is unknown.
1335 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1336
[email protected]07f54fcc2009-12-22 02:46:301337 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431338 bool IsDrawValid(
1339 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301340
[email protected]c13e1da62011-09-09 21:48:301341 // Returns true if successful, simulated will be true if attrib0 was
1342 // simulated.
[email protected]c6aef902012-02-14 03:31:421343 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431344 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]43410e92012-04-20 17:06:281345 void RestoreStateForAttrib(GLuint attrib);
[email protected]b1122982010-05-17 23:04:241346
[email protected]ef526492010-06-02 23:12:251347 // Returns true if textures were set.
1348 bool SetBlackTextureForNonRenderableTextures();
[email protected]3916c97e2010-02-25 03:20:501349 void RestoreStateForNonRenderableTextures();
1350
[email protected]8fbedc02010-11-18 18:43:401351 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421352 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431353 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421354 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401355 void RestoreStateForSimulatedFixedAttribs();
1356
[email protected]c6aef902012-02-14 03:31:421357 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1358 // cases (primcount is 0 for non-instanced).
1359 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431360 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421361 bool instanced, GLenum mode, GLint first, GLsizei count,
1362 GLsizei primcount);
1363 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431364 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421365 bool instanced, GLenum mode, GLsizei count, GLenum type,
1366 int32 offset, GLsizei primcount);
1367
[email protected]07f54fcc2009-12-22 02:46:301368 // Gets the buffer id for a given target.
[email protected]16ccec12013-02-28 03:40:211369 Buffer* GetBufferInfoForTarget(GLenum target) {
[email protected]07f54fcc2009-12-22 02:46:301370 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER);
[email protected]944b62f32012-09-27 02:20:461371 if (target == GL_ARRAY_BUFFER) {
[email protected]e259eb412012-10-13 05:47:241372 return state_.bound_array_buffer;
[email protected]944b62f32012-09-27 02:20:461373 } else {
[email protected]e259eb412012-10-13 05:47:241374 return state_.vertex_attrib_manager->element_array_buffer();
[email protected]944b62f32012-09-27 02:20:461375 }
[email protected]07f54fcc2009-12-22 02:46:301376 }
1377
[email protected]a93bb842010-02-16 23:03:471378 // Gets the texture id for a given target.
[email protected]370eaf12013-05-18 09:19:491379 TextureRef* GetTextureInfoForTarget(GLenum target) {
[email protected]e259eb412012-10-13 05:47:241380 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]370eaf12013-05-18 09:19:491381 TextureRef* texture = NULL;
[email protected]a93bb842010-02-16 23:03:471382 switch (target) {
1383 case GL_TEXTURE_2D:
[email protected]02965c22013-03-09 02:40:071384 texture = unit.bound_texture_2d;
[email protected]3916c97e2010-02-25 03:20:501385 break;
[email protected]a93bb842010-02-16 23:03:471386 case GL_TEXTURE_CUBE_MAP:
1387 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1388 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1389 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1390 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1391 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1392 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
[email protected]02965c22013-03-09 02:40:071393 texture = unit.bound_texture_cube_map;
[email protected]3916c97e2010-02-25 03:20:501394 break;
[email protected]61eeb33f2011-07-26 15:30:311395 case GL_TEXTURE_EXTERNAL_OES:
[email protected]02965c22013-03-09 02:40:071396 texture = unit.bound_texture_external_oes;
[email protected]61eeb33f2011-07-26 15:30:311397 break;
[email protected]e51bdf32011-11-23 22:21:461398 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]02965c22013-03-09 02:40:071399 texture = unit.bound_texture_rectangle_arb;
[email protected]e51bdf32011-11-23 22:21:461400 break;
[email protected]a93bb842010-02-16 23:03:471401 default:
1402 NOTREACHED();
[email protected]3916c97e2010-02-25 03:20:501403 return NULL;
[email protected]a93bb842010-02-16 23:03:471404 }
[email protected]02965c22013-03-09 02:40:071405 return texture;
[email protected]a93bb842010-02-16 23:03:471406 }
1407
[email protected]370eaf12013-05-18 09:19:491408 TextureRef* GetTextureInfoForTargetUnlessDefault(
[email protected]09d50362012-10-18 20:54:371409 GLenum target) {
[email protected]370eaf12013-05-18 09:19:491410 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:071411 if (!texture)
[email protected]09d50362012-10-18 20:54:371412 return NULL;
[email protected]02965c22013-03-09 02:40:071413 if (texture == texture_manager()->GetDefaultTextureInfo(target))
[email protected]09d50362012-10-18 20:54:371414 return NULL;
[email protected]02965c22013-03-09 02:40:071415 return texture;
[email protected]09d50362012-10-18 20:54:371416 }
1417
[email protected]61eeb33f2011-07-26 15:30:311418 GLenum GetBindTargetForSamplerType(GLenum type) {
1419 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461420 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1421 switch (type) {
1422 case GL_SAMPLER_2D:
1423 return GL_TEXTURE_2D;
1424 case GL_SAMPLER_CUBE:
1425 return GL_TEXTURE_CUBE_MAP;
1426 case GL_SAMPLER_EXTERNAL_OES:
1427 return GL_TEXTURE_EXTERNAL_OES;
1428 case GL_SAMPLER_2D_RECT_ARB:
1429 return GL_TEXTURE_RECTANGLE_ARB;
1430 }
1431
1432 NOTREACHED();
1433 return 0;
[email protected]61eeb33f2011-07-26 15:30:311434 }
1435
[email protected]8e3e0662010-08-23 18:46:301436 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061437 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1438 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301439 switch (target) {
1440 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451441 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]4d8f0dd2013-03-09 14:37:061442 framebuffer = state_.bound_draw_framebuffer;
[email protected]8e3e0662010-08-23 18:46:301443 break;
[email protected]ebfb73c2012-08-15 02:37:451444 case GL_READ_FRAMEBUFFER_EXT:
[email protected]4d8f0dd2013-03-09 14:37:061445 framebuffer = state_.bound_read_framebuffer;
[email protected]8e3e0662010-08-23 18:46:301446 break;
1447 default:
1448 NOTREACHED();
1449 break;
1450 }
[email protected]4d8f0dd2013-03-09 14:37:061451 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301452 }
1453
[email protected]ed9f9cd2013-02-27 21:12:351454 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201455 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271456 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201457 switch (target) {
1458 case GL_RENDERBUFFER:
[email protected]ee2a79c32013-03-10 03:50:271459 renderbuffer = state_.bound_renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201460 break;
1461 default:
1462 NOTREACHED();
1463 break;
1464 }
[email protected]ee2a79c32013-03-10 03:50:271465 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201466 }
1467
[email protected]f7b85372010-02-03 01:11:371468 // Validates the program and location for a glGetUniform call and returns
1469 // a SizeResult setup to receive the result. Returns true if glGetUniform
1470 // should be called.
1471 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121472 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371473 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121474 error::Error* error, GLint* real_location, GLuint* service_id,
1475 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371476
[email protected]1078f912011-12-23 13:12:141477 // Computes the estimated memory used for the backbuffer and passes it to
1478 // the tracing system.
[email protected]260ddc4e2012-06-28 00:01:531479 size_t GetBackbufferMemoryTotal();
[email protected]1078f912011-12-23 13:12:141480
[email protected]a10b4a02012-11-26 23:09:501481 virtual bool WasContextLost() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091482 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431483
[email protected]e51bdf32011-11-23 22:21:461484#if defined(OS_MACOSX)
1485 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1486#endif
1487
[email protected]81375742012-06-08 00:04:001488 // Validates the combination of texture parameters. For example validates that
1489 // for a given format the specific type, level and targets are valid.
1490 // Synthesizes the correct GL error if invalid. Returns true if valid.
1491 bool ValidateTextureParameters(
1492 const char* function_name,
1493 GLenum target, GLenum format, GLenum type, GLint level);
1494
[email protected]ad84a3a2012-06-08 21:42:431495 bool ValidateCompressedTexDimensions(
1496 const char* function_name,
1497 GLint level, GLsizei width, GLsizei height, GLenum format);
1498 bool ValidateCompressedTexFuncData(
1499 const char* function_name,
1500 GLsizei width, GLsizei height, GLenum format, size_t size);
1501 bool ValidateCompressedTexSubDimensions(
1502 const char* function_name,
1503 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1504 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351505 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431506
[email protected]ab09b612013-03-11 22:11:511507 void RenderWarning(const char* filename, int line, const std::string& msg);
1508 void PerformanceWarning(
1509 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011510
[email protected]62e155e2012-10-23 22:43:151511 const FeatureInfo::FeatureFlags& features() const {
1512 return feature_info_->feature_flags();
1513 }
1514
1515 const FeatureInfo::Workarounds& workarounds() const {
1516 return feature_info_->workarounds();
1517 }
1518
[email protected]a7266a92012-06-28 02:11:081519 bool ShouldDeferDraws() {
1520 return !offscreen_target_frame_buffer_.get() &&
[email protected]e259eb412012-10-13 05:47:241521 state_.bound_draw_framebuffer == NULL &&
[email protected]a7266a92012-06-28 02:11:081522 surface_->DeferDraws();
1523 }
1524
[email protected]09e17272012-11-30 10:30:441525 bool ShouldDeferReads() {
1526 return !offscreen_target_frame_buffer_.get() &&
1527 state_.bound_read_framebuffer == NULL &&
1528 surface_->DeferDraws();
1529 }
1530
[email protected]df37b9932013-03-08 05:21:421531 void ForceCompileShaderIfPending(Shader* shader);
[email protected]c447acd2012-07-23 23:48:411532
[email protected]96449d2c2009-11-25 00:01:321533 // Generate a member function prototype for each command in an automated and
1534 // typesafe way.
1535 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141536 Error Handle ## name( \
[email protected]ed9f9cd2013-02-27 21:12:351537 uint32 immediate_data_size, \
1538 const cmds::name& args); \
[email protected]96449d2c2009-11-25 00:01:321539
1540 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1541
1542 #undef GLES2_CMD_OP
1543
[email protected]2f2d7042010-04-14 21:45:581544 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381545 scoped_refptr<gfx::GLSurface> surface_;
1546 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021547
[email protected]a3ded6d2010-10-19 06:44:391548 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351549 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391550
[email protected]1d82e822013-04-10 21:32:321551 DebugMarkerManager debug_marker_manager_;
1552 Logger logger_;
1553
[email protected]e259eb412012-10-13 05:47:241554 // All the state for this context.
1555 ContextState state_;
1556
[email protected]6217d392010-03-25 22:08:351557 // A parent decoder can access this decoders saved offscreen frame buffer.
1558 // The parent pointer is reset if the parent is destroyed.
1559 base::WeakPtr<GLES2DecoderImpl> parent_;
1560
[email protected]34ff8b0c2010-10-01 20:06:021561 // Current width and height of the offscreen frame buffer.
1562 gfx::Size offscreen_size_;
1563
[email protected]96449d2c2009-11-25 00:01:321564 // Util to help with GL.
1565 GLES2Util util_;
1566
[email protected]43410e92012-04-20 17:06:281567 // unpack flip y as last set by glPixelStorei
1568 bool unpack_flip_y_;
1569
[email protected]6c75c712012-06-19 15:43:171570 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281571 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171572 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281573
[email protected]944b62f32012-09-27 02:20:461574 // Default vertex attribs manager, used when no VAOs are bound.
[email protected]ed9f9cd2013-02-27 21:12:351575 scoped_refptr<VertexAttribManager> default_vertex_attrib_manager_;
[email protected]07f54fcc2009-12-22 02:46:301576
[email protected]b1122982010-05-17 23:04:241577 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1578 GLuint attrib_0_buffer_id_;
1579
1580 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131581 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241582
[email protected]fc753442011-02-04 19:49:491583 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1584 bool attrib_0_buffer_matches_value_;
1585
[email protected]b1122982010-05-17 23:04:241586 // The size of attrib 0.
1587 GLsizei attrib_0_size_;
1588
[email protected]8fbedc02010-11-18 18:43:401589 // The buffer used to simulate GL_FIXED attribs.
1590 GLuint fixed_attrib_buffer_id_;
1591
1592 // The size of fiixed attrib buffer.
1593 GLsizei fixed_attrib_buffer_size_;
1594
[email protected]3a2e7c7b2010-08-06 01:12:281595 // state saved for clearing so we can clear render buffers and then
1596 // restore to these values.
[email protected]88a61bf2012-10-27 13:00:421597 bool clear_state_dirty_;
[email protected]3a2e7c7b2010-08-06 01:12:281598
[email protected]b9363b22010-06-09 22:06:151599 // The offscreen frame buffer that the client renders to. With EGL, the
1600 // depth and stencil buffers are separate. With regular GL there is a single
1601 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1602 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351603 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1604 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1605 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1606 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1607 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021608 GLenum offscreen_target_color_format_;
1609 GLenum offscreen_target_depth_format_;
1610 GLenum offscreen_target_stencil_format_;
1611 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561612 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351613
[email protected]de26b3c2011-08-03 21:54:271614 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351615 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1616 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491617 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351618 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271619
1620 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351621 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1622 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051623 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351624
[email protected]882ba1e22012-03-08 19:02:531625 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531626
[email protected]944b62f32012-09-27 02:20:461627 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1628
[email protected]9d37f062011-11-22 01:24:521629 base::Callback<void(gfx::Size)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001630
[email protected]840a7e462013-02-27 01:29:511631 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481632
[email protected]e3932abb2013-03-13 00:01:371633 ShaderCacheCallback shader_cache_callback_;
1634
[email protected]b0af4f52011-09-28 22:04:421635 StreamTextureManager* stream_texture_manager_;
[email protected]2a7568a2013-05-09 23:12:031636 scoped_ptr<AsyncPixelTransferDelegate> async_pixel_transfer_delegate_;
[email protected]b0af4f52011-09-28 22:04:421637
[email protected]32fe9aa2011-01-21 23:47:131638 // The format of the back buffer_
1639 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461640 bool back_buffer_has_depth_;
1641 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131642
[email protected]60f22d32012-12-12 00:31:581643 // Backbuffer attachments that are currently undefined.
1644 uint32 backbuffer_needs_clear_bits_;
1645
[email protected]473c01ccb2011-06-07 01:33:301646 bool teximage2d_faster_than_texsubimage2d_;
[email protected]473c01ccb2011-06-07 01:33:301647
[email protected]a3a93e7b2010-08-28 00:48:561648 // The current decoder error.
1649 error::Error current_decoder_error_;
1650
[email protected]b1d2dcb2010-05-17 19:24:181651 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041652 scoped_refptr<ShaderTranslator> vertex_translator_;
1653 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181654
[email protected]e82fb792011-09-22 00:33:291655 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411656
[email protected]915a59a12010-09-30 21:29:111657 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051658 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351659 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051660
[email protected]b493ee622011-04-13 23:52:001661 // This indicates all the following texSubImage2D calls that are part of the
1662 // failed texImage2D call should be ignored.
1663 bool tex_image_2d_failed_;
1664
[email protected]65225772011-05-12 21:10:241665 int frame_number_;
1666
[email protected]706b69f2012-07-27 04:59:301667 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431668 GLenum reset_status_;
1669
[email protected]f0d74742011-10-03 16:31:041670 // These flags are used to override the state of the shared feature_info_
1671 // member. Because the same FeatureInfo instance may be shared among many
1672 // contexts, the assumptions on the availablity of extensions in WebGL
1673 // contexts may be broken. These flags override the shared state to preserve
1674 // WebGL semantics.
1675 bool force_webgl_glsl_validation_;
1676 bool derivatives_explicitly_enabled_;
1677
[email protected]062c38b2012-01-18 03:25:101678 bool compile_shader_always_succeeds_;
1679
[email protected]cae20172012-12-07 00:06:191680 // Log extra info.
1681 bool service_logging_;
1682
[email protected]e51bdf32011-11-23 22:21:461683#if defined(OS_MACOSX)
1684 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap;
1685 TextureToIOSurfaceMap texture_to_io_surface_map_;
1686#endif
1687
[email protected]c826d732012-02-09 04:40:261688 typedef std::vector<GLES2DecoderImpl*> ChildList;
1689 ChildList children_;
1690
[email protected]43410e92012-04-20 17:06:281691 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1692
[email protected]1868a342012-11-07 15:56:021693 // Cached values of the currently assigned viewport dimensions.
1694 GLsizei viewport_max_width_;
1695 GLsizei viewport_max_height_;
1696
[email protected]63b465922012-09-06 02:04:521697 // Command buffer stats.
1698 int texture_upload_count_;
1699 base::TimeDelta total_texture_upload_time_;
1700 base::TimeDelta total_processing_commands_time_;
1701
[email protected]fb97b662013-02-20 23:02:141702 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]94307712012-11-16 23:26:111703
[email protected]96449d2c2009-11-25 00:01:321704 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1705};
1706
[email protected]ab09b612013-03-11 22:11:511707ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
1708 const char* function_name, GLES2DecoderImpl* decoder)
1709 : function_name_(function_name),
1710 decoder_(decoder) {
[email protected]d3eba342013-04-18 21:11:501711 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder_->GetErrorState(),
1712 function_name_);
[email protected]6217d392010-03-25 22:08:351713}
1714
1715ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]d3eba342013-04-18 21:11:501716 ERRORSTATE_CLEAR_REAL_GL_ERRORS(decoder_->GetErrorState(), function_name_);
[email protected]6217d392010-03-25 22:08:351717}
1718
1719ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder,
1720 GLuint id)
1721 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511722 ScopedGLErrorSuppressor suppressor(
1723 "ScopedTexture2DBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351724
1725 // TODO(apatrick): Check if there are any other states that need to be reset
1726 // before binding a new texture.
1727 glActiveTexture(GL_TEXTURE0);
1728 glBindTexture(GL_TEXTURE_2D, id);
1729}
1730
1731ScopedTexture2DBinder::~ScopedTexture2DBinder() {
[email protected]ab09b612013-03-11 22:11:511732 ScopedGLErrorSuppressor suppressor(
1733 "ScopedTexture2DBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301734 decoder_->RestoreCurrentTexture2DBindings();
[email protected]6217d392010-03-25 22:08:351735}
1736
1737ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder,
1738 GLuint id)
1739 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511740 ScopedGLErrorSuppressor suppressor(
1741 "ScopedRenderBufferBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351742 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1743}
1744
1745ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511746 ScopedGLErrorSuppressor suppressor(
1747 "ScopedRenderBufferBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301748 decoder_->RestoreCurrentRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351749}
1750
1751ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1752 GLuint id)
1753 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511754 ScopedGLErrorSuppressor suppressor(
1755 "ScopedFrameBufferBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351756 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451757 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351758}
1759
1760ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511761 ScopedGLErrorSuppressor suppressor(
1762 "ScopedFrameBufferBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301763 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351764}
1765
[email protected]34ff8b0c2010-10-01 20:06:021766ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271767 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521768 : decoder_(decoder) {
[email protected]34ff8b0c2010-10-01 20:06:021769 resolve_and_bind_ = (decoder_->offscreen_target_frame_buffer_.get() &&
1770 decoder_->IsOffscreenBufferMultisampled() &&
[email protected]e259eb412012-10-13 05:47:241771 (!decoder_->state_.bound_read_framebuffer.get() ||
[email protected]c0701082011-04-20 00:34:521772 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021773 if (!resolve_and_bind_)
1774 return;
1775
[email protected]ab09b612013-03-11 22:11:511776 ScopedGLErrorSuppressor suppressor(
1777 "ScopedResolvedFrameBufferBinder::ctor", decoder_);
[email protected]34ff8b0c2010-10-01 20:06:021778 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1779 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271780 GLuint targetid;
1781 if (internal) {
1782 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1783 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351784 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271785 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351786 decoder_->offscreen_resolved_color_texture_.reset(
1787 new BackTexture(decoder_));
[email protected]de26b3c2011-08-03 21:54:271788 decoder_->offscreen_resolved_color_texture_->Create();
1789
1790 DCHECK(decoder_->offscreen_saved_color_format_);
1791 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091792 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1793 false);
[email protected]de26b3c2011-08-03 21:54:271794 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1795 decoder_->offscreen_resolved_color_texture_.get());
1796 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1797 GL_FRAMEBUFFER_COMPLETE) {
1798 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1799 << "because offscreen resolved FBO was incomplete.";
1800 return;
1801 }
1802 }
1803 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1804 } else {
1805 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1806 }
1807 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021808 const int width = decoder_->offscreen_size_.width();
1809 const int height = decoder_->offscreen_size_.height();
[email protected]8c3e68782010-10-27 16:41:181810 glDisable(GL_SCISSOR_TEST);
[email protected]57edfdad2012-02-07 04:57:151811 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021812 glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height,
1813 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1814 } else {
1815 glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height,
1816 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1817 }
[email protected]de26b3c2011-08-03 21:54:271818 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021819}
1820
1821ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1822 if (!resolve_and_bind_)
1823 return;
1824
[email protected]ab09b612013-03-11 22:11:511825 ScopedGLErrorSuppressor suppressor(
1826 "ScopedResolvedFrameBufferBinder::dtor", decoder_);
[email protected]34ff8b0c2010-10-01 20:06:021827 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:221828 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]8c3e68782010-10-27 16:41:181829 glEnable(GL_SCISSOR_TEST);
1830 }
[email protected]34ff8b0c2010-10-01 20:06:021831}
1832
[email protected]63b465922012-09-06 02:04:521833ScopedTextureUploadTimer::ScopedTextureUploadTimer(GLES2DecoderImpl* decoder)
1834 : decoder_(decoder),
1835 begin_time_(base::TimeTicks::HighResNow()) {
1836}
1837
1838ScopedTextureUploadTimer::~ScopedTextureUploadTimer() {
1839 decoder_->texture_upload_count_++;
1840 decoder_->total_texture_upload_time_ +=
1841 base::TimeTicks::HighResNow() - begin_time_;
1842}
1843
[email protected]ed9f9cd2013-02-27 21:12:351844BackTexture::BackTexture(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:351845 : decoder_(decoder),
[email protected]7989c9e2013-01-23 06:39:261846 memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged),
[email protected]68e81a4a62012-12-13 01:16:481847 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251848 id_(0) {
[email protected]6217d392010-03-25 22:08:351849}
1850
[email protected]ed9f9cd2013-02-27 21:12:351851BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:351852 // This does not destroy the render texture because that would require that
1853 // the associated GL context was current. Just check that it was explicitly
1854 // destroyed.
1855 DCHECK_EQ(id_, 0u);
1856}
1857
[email protected]ed9f9cd2013-02-27 21:12:351858void BackTexture::Create() {
[email protected]ab09b612013-03-11 22:11:511859 ScopedGLErrorSuppressor suppressor("BackTexture::Create", decoder_);
[email protected]6217d392010-03-25 22:08:351860 Destroy();
1861 glGenTextures(1, &id_);
[email protected]3a4d0c52011-06-29 23:11:581862 ScopedTexture2DBinder binder(decoder_, id_);
1863 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1864 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1865 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1866 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:161867
1868 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
1869 // never called on an offscreen context, no data will ever be uploaded to the
1870 // saved offscreen color texture (it is deferred until to when SwapBuffers
1871 // is called). My idea is that some nvidia drivers might have a bug where
1872 // deleting a texture that has never been populated might cause a
1873 // crash.
1874 glTexImage2D(
1875 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:481876
1877 bytes_allocated_ = 16u * 16u * 4u;
1878 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:351879}
1880
[email protected]ed9f9cd2013-02-27 21:12:351881bool BackTexture::AllocateStorage(
1882 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:351883 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:511884 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage", decoder_);
[email protected]6217d392010-03-25 22:08:351885 ScopedTexture2DBinder binder(decoder_, id_);
[email protected]678a73f2012-12-19 19:22:091886 uint32 image_size = 0;
1887 GLES2Util::ComputeImageDataSizes(
1888 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
1889 NULL, NULL);
1890
[email protected]7989c9e2013-01-23 06:39:261891 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
1892 return false;
1893 }
1894
[email protected]40d90a22013-04-09 03:39:551895 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:091896 if (zero) {
1897 zero_data.reset(new char[image_size]);
1898 memset(zero_data.get(), 0, image_size);
1899 }
[email protected]6217d392010-03-25 22:08:351900
[email protected]8f1d2aa2013-05-10 23:45:381901 glTexImage2D(GL_TEXTURE_2D,
1902 0, // mip level
1903 format,
1904 size.width(),
1905 size.height(),
1906 0, // border
1907 format,
1908 GL_UNSIGNED_BYTE,
1909 zero_data.get());
[email protected]6217d392010-03-25 22:08:351910
[email protected]d37231fa2010-04-09 21:16:021911 size_ = size;
1912
[email protected]1078f912011-12-23 13:12:141913 bool success = glGetError() == GL_NO_ERROR;
1914 if (success) {
[email protected]68e81a4a62012-12-13 01:16:481915 memory_tracker_.TrackMemFree(bytes_allocated_);
1916 bytes_allocated_ = image_size;
1917 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:141918 }
1919 return success;
[email protected]6217d392010-03-25 22:08:351920}
1921
[email protected]ed9f9cd2013-02-27 21:12:351922void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:351923 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:511924 ScopedGLErrorSuppressor suppressor("BackTexture::Copy", decoder_);
[email protected]6217d392010-03-25 22:08:351925 ScopedTexture2DBinder binder(decoder_, id_);
1926 glCopyTexImage2D(GL_TEXTURE_2D,
1927 0, // level
[email protected]3a4d0c52011-06-29 23:11:581928 format,
[email protected]6217d392010-03-25 22:08:351929 0, 0,
1930 size.width(),
1931 size.height(),
1932 0); // border
1933}
1934
[email protected]ed9f9cd2013-02-27 21:12:351935void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:351936 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:511937 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:351938 glDeleteTextures(1, &id_);
1939 id_ = 0;
1940 }
[email protected]68e81a4a62012-12-13 01:16:481941 memory_tracker_.TrackMemFree(bytes_allocated_);
1942 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:351943}
1944
[email protected]ed9f9cd2013-02-27 21:12:351945void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:051946 id_ = 0;
1947}
1948
[email protected]ed9f9cd2013-02-27 21:12:351949BackRenderbuffer::BackRenderbuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:351950 : decoder_(decoder),
[email protected]7989c9e2013-01-23 06:39:261951 memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged),
[email protected]68e81a4a62012-12-13 01:16:481952 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251953 id_(0) {
[email protected]6217d392010-03-25 22:08:351954}
1955
[email protected]ed9f9cd2013-02-27 21:12:351956BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:351957 // This does not destroy the render buffer because that would require that
1958 // the associated GL context was current. Just check that it was explicitly
1959 // destroyed.
1960 DCHECK_EQ(id_, 0u);
1961}
1962
[email protected]ed9f9cd2013-02-27 21:12:351963void BackRenderbuffer::Create() {
[email protected]ab09b612013-03-11 22:11:511964 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create", decoder_);
[email protected]6217d392010-03-25 22:08:351965 Destroy();
1966 glGenRenderbuffersEXT(1, &id_);
1967}
1968
[email protected]ed9f9cd2013-02-27 21:12:351969bool BackRenderbuffer::AllocateStorage(const gfx::Size& size, GLenum format,
1970 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:511971 ScopedGLErrorSuppressor suppressor(
1972 "BackRenderbuffer::AllocateStorage", decoder_);
[email protected]6217d392010-03-25 22:08:351973 ScopedRenderBufferBinder binder(decoder_, id_);
[email protected]7989c9e2013-01-23 06:39:261974
1975 uint32 estimated_size = 0;
1976 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
1977 size.width(), size.height(), samples, format, &estimated_size)) {
1978 return false;
1979 }
1980
1981 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
1982 return false;
1983 }
1984
[email protected]34ff8b0c2010-10-01 20:06:021985 if (samples <= 1) {
1986 glRenderbufferStorageEXT(GL_RENDERBUFFER,
1987 format,
1988 size.width(),
1989 size.height());
1990 } else {
[email protected]57edfdad2012-02-07 04:57:151991 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021992 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER,
1993 samples,
1994 format,
1995 size.width(),
1996 size.height());
1997 } else {
1998 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
1999 samples,
2000 format,
2001 size.width(),
2002 size.height());
2003 }
2004 }
[email protected]1078f912011-12-23 13:12:142005 bool success = glGetError() == GL_NO_ERROR;
2006 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482007 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262008 bytes_allocated_ = estimated_size;
[email protected]68e81a4a62012-12-13 01:16:482009 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142010 }
2011 return success;
[email protected]6217d392010-03-25 22:08:352012}
2013
[email protected]ed9f9cd2013-02-27 21:12:352014void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352015 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:512016 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:352017 glDeleteRenderbuffersEXT(1, &id_);
2018 id_ = 0;
2019 }
[email protected]68e81a4a62012-12-13 01:16:482020 memory_tracker_.TrackMemFree(bytes_allocated_);
2021 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352022}
2023
[email protected]ed9f9cd2013-02-27 21:12:352024void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052025 id_ = 0;
2026}
2027
[email protected]ed9f9cd2013-02-27 21:12:352028BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352029 : decoder_(decoder),
2030 id_(0) {
2031}
2032
[email protected]ed9f9cd2013-02-27 21:12:352033BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352034 // This does not destroy the frame buffer because that would require that
2035 // the associated GL context was current. Just check that it was explicitly
2036 // destroyed.
2037 DCHECK_EQ(id_, 0u);
2038}
2039
[email protected]ed9f9cd2013-02-27 21:12:352040void BackFramebuffer::Create() {
[email protected]ab09b612013-03-11 22:11:512041 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create", decoder_);
[email protected]6217d392010-03-25 22:08:352042 Destroy();
2043 glGenFramebuffersEXT(1, &id_);
2044}
2045
[email protected]ed9f9cd2013-02-27 21:12:352046void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352047 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512048 ScopedGLErrorSuppressor suppressor(
2049 "BackFramebuffer::AttachRenderTexture", decoder_);
[email protected]6217d392010-03-25 22:08:352050 ScopedFrameBufferBinder binder(decoder_, id_);
2051 GLuint attach_id = texture ? texture->id() : 0;
2052 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2053 GL_COLOR_ATTACHMENT0,
2054 GL_TEXTURE_2D,
2055 attach_id,
2056 0);
2057}
2058
[email protected]ed9f9cd2013-02-27 21:12:352059void BackFramebuffer::AttachRenderBuffer(GLenum target,
2060 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352061 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512062 ScopedGLErrorSuppressor suppressor(
2063 "BackFramebuffer::AttachRenderBuffer", decoder_);
[email protected]6217d392010-03-25 22:08:352064 ScopedFrameBufferBinder binder(decoder_, id_);
2065 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2066 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152067 target,
[email protected]6217d392010-03-25 22:08:352068 GL_RENDERBUFFER,
2069 attach_id);
2070}
2071
[email protected]ed9f9cd2013-02-27 21:12:352072void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352073 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:512074 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:352075 glDeleteFramebuffersEXT(1, &id_);
2076 id_ = 0;
2077 }
2078}
2079
[email protected]ed9f9cd2013-02-27 21:12:352080void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052081 id_ = 0;
2082}
2083
[email protected]ed9f9cd2013-02-27 21:12:352084GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352085 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512086 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus", decoder_);
[email protected]6217d392010-03-25 22:08:352087 ScopedFrameBufferBinder binder(decoder_, id_);
2088 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2089}
2090
[email protected]aa7666122011-09-02 19:45:522091GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2092 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322093}
2094
[email protected]aa7666122011-09-02 19:45:522095GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392096 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572097 group_(group),
[email protected]1d82e822013-04-10 21:32:322098 logger_(&debug_marker_manager_),
[email protected]d3eba342013-04-18 21:11:502099 state_(group_->feature_info(), &logger_),
[email protected]43410e92012-04-20 17:06:282100 unpack_flip_y_(false),
2101 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172102 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242103 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492104 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242105 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402106 fixed_attrib_buffer_id_(0),
2107 fixed_attrib_buffer_size_(0),
[email protected]88a61bf2012-10-27 13:00:422108 clear_state_dirty_(true),
[email protected]34ff8b0c2010-10-01 20:06:022109 offscreen_target_color_format_(0),
2110 offscreen_target_depth_format_(0),
2111 offscreen_target_stencil_format_(0),
2112 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562113 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052114 offscreen_saved_color_format_(0),
[email protected]b0af4f52011-09-28 22:04:422115 stream_texture_manager_(NULL),
[email protected]32fe9aa2011-01-21 23:47:132116 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462117 back_buffer_has_depth_(false),
2118 back_buffer_has_stencil_(false),
[email protected]60f22d32012-12-12 00:31:582119 backbuffer_needs_clear_bits_(0),
[email protected]473c01ccb2011-06-07 01:33:302120 teximage2d_faster_than_texsubimage2d_(true),
[email protected]a3a93e7b2010-08-28 00:48:562121 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052122 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112123 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002124 feature_info_(group_->feature_info()),
[email protected]65225772011-05-12 21:10:242125 tex_image_2d_failed_(false),
[email protected]38d139d2011-07-14 00:38:432126 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302127 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512128 reset_status_(GL_NO_ERROR),
[email protected]f0d74742011-10-03 16:31:042129 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102130 derivatives_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282131 compile_shader_always_succeeds_(false),
[email protected]cae20172012-12-07 00:06:192132 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2133 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022134 viewport_max_width_(0),
2135 viewport_max_height_(0),
[email protected]63b465922012-09-06 02:04:522136 texture_upload_count_(0) {
[email protected]3b1ecc262011-08-03 22:49:572137 DCHECK(group);
2138
[email protected]b1122982010-05-17 23:04:242139 attrib_0_value_.v[0] = 0.0f;
2140 attrib_0_value_.v[1] = 0.0f;
2141 attrib_0_value_.v[2] = 0.0f;
2142 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152143
[email protected]c2f8c8402010-12-06 18:07:242144 // The shader translator is used for WebGL even when running on EGL
2145 // because additional restrictions are needed (like only enabling
2146 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562147 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2148 // the empty string to CompileShader and this is not a valid shader.
2149 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002150 CommandLine::ForCurrentProcess()->HasSwitch(
2151 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152152 use_shader_translator_ = false;
2153 }
[email protected]473c01ccb2011-06-07 01:33:302154
[email protected]a39370652012-09-25 21:52:132155 // TODO(gman): Consider setting this based on GPU and/or driver.
[email protected]473c01ccb2011-06-07 01:33:302156 if (IsAngle()) {
2157 teximage2d_faster_than_texsubimage2d_ = false;
[email protected]473c01ccb2011-06-07 01:33:302158 }
[email protected]96449d2c2009-11-25 00:01:322159}
2160
[email protected]80eb6b52012-01-19 00:14:412161GLES2DecoderImpl::~GLES2DecoderImpl() {
2162}
2163
[email protected]c410da802011-03-14 19:17:412164bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382165 const scoped_refptr<gfx::GLSurface>& surface,
2166 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232167 bool offscreen,
[email protected]c410da802011-03-14 19:17:412168 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292169 const DisallowedFeatures& disallowed_features,
[email protected]c410da802011-03-14 19:17:412170 const char* allowed_extensions,
[email protected]3c644d82011-06-20 19:58:242171 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322172 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382173 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302174 DCHECK(!context_.get());
2175
[email protected]55e136f2013-04-03 18:50:062176 set_initialized();
[email protected]fb97b662013-02-20 23:02:142177 gpu_tracer_ = GPUTracer::Create();
2178
[email protected]e844ae22012-01-14 03:36:262179 if (CommandLine::ForCurrentProcess()->HasSwitch(
2180 switches::kEnableGPUDebugging)) {
2181 set_debug(true);
2182 }
2183
[email protected]39ba4f02012-03-26 01:16:002184 if (CommandLine::ForCurrentProcess()->HasSwitch(
2185 switches::kEnableGPUCommandLogging)) {
2186 set_log_commands(true);
2187 }
2188
[email protected]062c38b2012-01-18 03:25:102189 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2190 switches::kCompileShaderAlwaysSucceeds);
2191
[email protected]f62a5ab2011-05-23 20:34:152192
[email protected]63c9b052012-05-17 18:27:382193 // Take ownership of the context and surface. The surface can be replaced with
2194 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382195 context_ = context;
[email protected]63c9b052012-05-17 18:27:382196 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182197
[email protected]c4485aad62012-12-17 10:19:092198 if (!group_->Initialize(this, disallowed_features, allowed_extensions)) {
[email protected]09ddb91f2011-04-14 23:16:222199 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392200 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422201 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382202 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032203 return false;
[email protected]a3ded6d2010-10-19 06:44:392204 }
[email protected]b64c24952012-04-19 03:20:272205 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282206
[email protected]e82fb792011-09-22 00:33:292207 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502208
[email protected]af6380962012-11-29 23:24:132209 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]944b62f32012-09-27 02:20:462210 default_vertex_attrib_manager_ = new VertexAttribManager();
2211 default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs());
2212
[email protected]ab4fd7282012-10-12 16:25:572213 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call
2214 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322215
[email protected]d6ca4792012-05-14 19:24:132216 query_manager_.reset(new QueryManager(this, feature_info_));
[email protected]944b62f32012-09-27 02:20:462217 vertex_array_manager_.reset(new VertexArrayManager());
[email protected]882ba1e22012-03-08 19:02:532218
[email protected]302ce6d2011-07-07 23:28:112219 util_.set_num_compressed_texture_formats(
2220 validators_->compressed_texture_format.GetValues().size());
2221
[email protected]1071e572011-02-09 20:00:122222 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2223 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2224 // OpenGL ES 2.0 does not have this issue.
2225 glEnableVertexAttribArray(0);
2226 }
[email protected]b1122982010-05-17 23:04:242227 glGenBuffersARB(1, &attrib_0_buffer_id_);
2228 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2229 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2230 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402231 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082232
[email protected]1868a342012-11-07 15:56:022233 state_.texture_units.resize(group_->max_texture_units());
2234 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492235 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312236 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492237 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152238 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492239 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072240 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492241 state_.texture_units[tt].bound_texture_external_oes = ref;
2242 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref->service_id());
[email protected]61eeb33f2011-07-26 15:30:312243 }
[email protected]62e155e2012-10-23 22:43:152244 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492245 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072246 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492247 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
2248 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref->service_id());
[email protected]e51bdf32011-11-23 22:21:462249 }
[email protected]370eaf12013-05-18 09:19:492250 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2251 state_.texture_units[tt].bound_texture_cube_map = ref;
2252 glBindTexture(GL_TEXTURE_CUBE_MAP, ref->service_id());
2253 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2254 state_.texture_units[tt].bound_texture_2d = ref;
2255 glBindTexture(GL_TEXTURE_2D, ref->service_id());
[email protected]1958e0e2010-04-22 05:17:152256 }
[email protected]00f893d2010-08-24 18:55:492257 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502258 CHECK_GL_ERROR();
2259
[email protected]297ca1c2011-06-20 23:08:462260 ContextCreationAttribParser attrib_parser;
2261 if (!attrib_parser.Parse(attribs))
2262 return false;
[email protected]41c56362011-06-14 16:47:432263
[email protected]297ca1c2011-06-20 23:08:462264 // These are NOT if the back buffer has these proprorties. They are
2265 // if we want the command buffer to enforce them regardless of what
2266 // the real backbuffer is assuming the real back buffer gives us more than
2267 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2268 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2269 // can't do anything about that.
2270
2271 GLint v = 0;
2272 glGetIntegerv(GL_ALPHA_BITS, &v);
2273 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2274 // user requested RGB then RGB. If the user did not specify a preference than
2275 // use whatever we were given. Same for DEPTH and STENCIL.
2276 back_buffer_color_format_ =
2277 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2278 glGetIntegerv(GL_DEPTH_BITS, &v);
2279 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2280 glGetIntegerv(GL_STENCIL_BITS, &v);
2281 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
2282
[email protected]069944672012-04-25 20:52:232283 if (offscreen) {
[email protected]34ff8b0c2010-10-01 20:06:022284 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
[email protected]b0609652012-12-14 07:24:542285 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022286 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432287 // max_sample_count must be initialized to a sane value. If
2288 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2289 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022290 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2291 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2292 max_sample_count);
2293 } else {
2294 offscreen_target_samples_ = 1;
2295 }
[email protected]8a61d872012-01-20 12:43:562296 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
[email protected]34ff8b0c2010-10-01 20:06:022297
2298 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2299 const bool rgb8_supported =
2300 context_->HasExtension("GL_OES_rgb8_rgba8");
2301 // The only available default render buffer formats in GLES2 have very
2302 // little precision. Don't enable multisampling unless 8-bit render
2303 // buffer formats are available--instead fall back to 8-bit textures.
2304 if (rgb8_supported && offscreen_target_samples_ > 1) {
2305 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2306 GL_RGBA8 : GL_RGB8;
2307 } else {
2308 offscreen_target_samples_ = 1;
2309 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2310 GL_RGBA : GL_RGB;
2311 }
2312
2313 // ANGLE only supports packed depth/stencil formats, so use it if it is
2314 // available.
2315 const bool depth24_stencil8_supported =
2316 context_->HasExtension("GL_OES_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272317 VLOG(1) << "GL_OES_packed_depth_stencil "
2318 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]71ee3642010-10-14 18:08:002319 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2320 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022321 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2322 offscreen_target_stencil_format_ = 0;
2323 } else {
2324 // It may be the case that this depth/stencil combination is not
2325 // supported, but this will be checked later by CheckFramebufferStatus.
2326 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2327 GL_DEPTH_COMPONENT16 : 0;
2328 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2329 GL_STENCIL_INDEX8 : 0;
2330 }
2331 } else {
2332 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2333 GL_RGBA : GL_RGB;
2334
2335 // If depth is requested at all, use the packed depth stencil format if
2336 // it's available, as some desktop GL drivers don't support any non-packed
2337 // formats for depth attachments.
2338 const bool depth24_stencil8_supported =
2339 context_->HasExtension("GL_EXT_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272340 VLOG(1) << "GL_EXT_packed_depth_stencil "
2341 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022342
[email protected]71ee3642010-10-14 18:08:002343 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2344 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022345 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2346 offscreen_target_stencil_format_ = 0;
2347 } else {
2348 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2349 GL_DEPTH_COMPONENT : 0;
2350 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2351 GL_STENCIL_INDEX : 0;
2352 }
2353 }
2354
[email protected]97872062010-11-03 19:07:052355 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2356 GL_RGBA : GL_RGB;
2357
[email protected]6217d392010-03-25 22:08:352358 // Create the target frame buffer. This is the one that the client renders
2359 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352360 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352361 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022362 // Due to GLES2 format limitations, either the color texture (for
2363 // non-multisampling) or the color render buffer (for multisampling) will be
2364 // attached to the offscreen frame buffer. The render buffer has more
2365 // limited formats available to it, but the texture can't do multisampling.
2366 if (IsOffscreenBufferMultisampled()) {
[email protected]ed9f9cd2013-02-27 21:12:352367 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022368 offscreen_target_color_render_buffer_->Create();
2369 } else {
[email protected]ed9f9cd2013-02-27 21:12:352370 offscreen_target_color_texture_.reset(new BackTexture(this));
[email protected]34ff8b0c2010-10-01 20:06:022371 offscreen_target_color_texture_->Create();
2372 }
[email protected]ed9f9cd2013-02-27 21:12:352373 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]b9363b22010-06-09 22:06:152374 offscreen_target_depth_render_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:352375 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]b9363b22010-06-09 22:06:152376 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352377
2378 // Create the saved offscreen texture. The target frame buffer is copied
2379 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352380 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022381 offscreen_saved_frame_buffer_->Create();
2382 //
[email protected]ed9f9cd2013-02-27 21:12:352383 offscreen_saved_color_texture_.reset(new BackTexture(this));
[email protected]6217d392010-03-25 22:08:352384 offscreen_saved_color_texture_->Create();
2385
[email protected]6217d392010-03-25 22:08:352386 // Allocate the render buffers at their initial size and check the status
2387 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592388 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012389 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382390 Destroy(true);
[email protected]6217d392010-03-25 22:08:352391 return false;
2392 }
2393
[email protected]678a73f2012-12-19 19:22:092394 // Allocate the offscreen saved color texture.
2395 DCHECK(offscreen_saved_color_format_);
2396 offscreen_saved_color_texture_->AllocateStorage(
2397 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2398
2399 offscreen_saved_frame_buffer_->AttachRenderTexture(
2400 offscreen_saved_color_texture_.get());
2401 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2402 GL_FRAMEBUFFER_COMPLETE) {
2403 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2404 Destroy(true);
2405 return false;
2406 }
2407
[email protected]6217d392010-03-25 22:08:352408 // Bind to the new default frame buffer (the offscreen target frame buffer).
2409 // This should now be associated with ID zero.
2410 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2411 }
2412
[email protected]76a0ee102010-04-07 21:03:042413 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2414 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2415 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372416 // mailing list archives. It also implicitly enables the desktop GL
2417 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2418 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152419 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2420 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372421 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152422 }
[email protected]de17df392010-04-23 21:09:412423
[email protected]706b69f2012-07-27 04:59:302424 has_robustness_extension_ =
2425 context->HasExtension("GL_ARB_robustness") ||
2426 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432427
[email protected]c2f8c8402010-12-06 18:07:242428 if (!InitializeShaderTranslator()) {
2429 return false;
[email protected]de17df392010-04-23 21:09:412430 }
[email protected]76a0ee102010-04-07 21:03:042431
[email protected]e259eb412012-10-13 05:47:242432 state_.viewport_width = size.width();
2433 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282434
[email protected]5904806b2012-05-08 18:10:222435 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282436 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022437 viewport_max_width_ = viewport_params[0];
2438 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282439
[email protected]88a61bf2012-10-27 13:00:422440 state_.scissor_width = state_.viewport_width;
2441 state_.scissor_height = state_.viewport_height;
2442
[email protected]11f3e702012-06-19 19:00:012443 // Set all the default state because some GL drivers get it wrong.
[email protected]f731b9462012-10-30 00:35:222444 state_.InitCapabilities();
2445 state_.InitState();
[email protected]e259eb412012-10-13 05:47:242446 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]88a61bf2012-10-27 13:00:422447 glHint(GL_GENERATE_MIPMAP_HINT, state_.hint_generate_mipmap);
[email protected]e259eb412012-10-13 05:47:242448 glPixelStorei(GL_PACK_ALIGNMENT, state_.pack_alignment);
[email protected]e259eb412012-10-13 05:47:242449 glPixelStorei(GL_UNPACK_ALIGNMENT, state_.unpack_alignment);
[email protected]11f3e702012-06-19 19:00:012450
2451 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2452 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2453 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2454 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2455
[email protected]561cc0a62013-05-07 18:34:452456 // Clear the backbuffer.
2457 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2458
[email protected]62e155e2012-10-23 22:43:152459 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462460 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2461 }
[email protected]dd289a5d62012-06-30 22:05:462462
[email protected]9b753992013-04-27 02:04:412463 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2464 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242465 }
[email protected]85cb4682013-04-20 00:54:242466
[email protected]97419c02013-04-10 02:52:382467 // Only compositor contexts are known to use only the subset of GL
2468 // that can be safely migrated between the iGPU and the dGPU. Mark
2469 // those contexts as safe to forcibly transition between the GPUs.
2470 // http://crbug.com/180876, http://crbug.com/227228
2471 if (!offscreen)
2472 context_->SetSafeToForceGpuSwitch();
2473
[email protected]32145a92012-12-17 09:01:592474 // Create a delegate to perform async pixel transfers.
[email protected]373cfd02013-04-25 20:20:212475 async_pixel_transfer_delegate_.reset(
[email protected]2a7568a2013-05-09 23:12:032476 AsyncPixelTransferDelegate::Create(context.get()));
[email protected]32145a92012-12-17 09:01:592477
[email protected]246a70452010-03-05 21:53:502478 return true;
[email protected]96449d2c2009-11-25 00:01:322479}
2480
[email protected]302ce6d2011-07-07 23:28:112481void GLES2DecoderImpl::UpdateCapabilities() {
2482 util_.set_num_compressed_texture_formats(
2483 validators_->compressed_texture_format.GetValues().size());
2484 util_.set_num_shader_binary_formats(
2485 validators_->shader_binary_format.GetValues().size());
2486}
2487
[email protected]c2f8c8402010-12-06 18:07:242488bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442489 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2490
[email protected]c2f8c8402010-12-06 18:07:242491 if (!use_shader_translator_) {
2492 return true;
2493 }
2494 ShBuiltInResources resources;
2495 ShInitBuiltInResources(&resources);
2496 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2497 resources.MaxVertexUniformVectors =
2498 group_->max_vertex_uniform_vectors();
2499 resources.MaxVaryingVectors = group_->max_varying_vectors();
2500 resources.MaxVertexTextureImageUnits =
2501 group_->max_vertex_texture_image_units();
2502 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2503 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2504 resources.MaxFragmentUniformVectors =
2505 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492506 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]f0d74742011-10-03 16:31:042507
[email protected]9e98f61b2013-03-05 02:21:142508#if (ANGLE_SH_VERSION >= 110)
[email protected]8dc1bf92013-03-12 03:58:212509 GLint range[2];
2510 GLint precision = 0;
2511 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2512 range, &precision);
2513 resources.FragmentPrecisionHigh = ((range[0] >= 62) &&
2514 (range[1] >= 62) &&
2515 (precision >= 16));
[email protected]9e98f61b2013-03-05 02:21:142516#endif
2517
[email protected]f0d74742011-10-03 16:31:042518 if (force_webgl_glsl_validation_) {
2519 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
2520 } else {
2521 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152522 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462523 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152524 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062525 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152526 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492527 resources.EXT_draw_buffers =
2528 features().ext_draw_buffers ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042529 }
2530
[email protected]26b61442013-03-17 16:12:012531 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2532 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052533 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022534#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]6aedcdc2013-01-24 01:25:052535 resources.HashFunction = &CityHashForAngle;
[email protected]3d944a82013-02-12 19:09:022536#else
2537 resources.HashFunction = &CityHash64;
2538#endif
[email protected]6aedcdc2013-01-24 01:25:052539 else
2540 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122541 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2542 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2543 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
2544 ShaderTranslatorInterface::GlslBuiltInFunctionBehavior function_behavior =
[email protected]62e155e2012-10-23 22:43:152545 workarounds().needs_glsl_built_in_function_emulation ?
[email protected]a2a0fe762011-09-20 00:59:122546 ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated :
2547 ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal;
[email protected]87fb6ab2012-06-13 22:28:042548
2549 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance();
2550 vertex_translator_ = cache->GetTranslator(
2551 SH_VERTEX_SHADER, shader_spec, &resources,
2552 implementation_type, function_behavior);
2553 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242554 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382555 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242556 return false;
2557 }
[email protected]87fb6ab2012-06-13 22:28:042558
2559 fragment_translator_ = cache->GetTranslator(
2560 SH_FRAGMENT_SHADER, shader_spec, &resources,
2561 implementation_type, function_behavior);
2562 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242563 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382564 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242565 return false;
2566 }
2567 return true;
2568}
2569
[email protected]ae51d192010-04-27 00:48:032570bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472571 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352572 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032573 return false;
2574 }
2575 }
[email protected]40d90a22013-04-09 03:39:552576 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032577 glGenBuffersARB(n, service_ids.get());
2578 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352579 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032580 }
2581 return true;
2582}
2583
2584bool GLES2DecoderImpl::GenFramebuffersHelper(
2585 GLsizei n, const GLuint* client_ids) {
2586 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352587 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032588 return false;
2589 }
2590 }
[email protected]40d90a22013-04-09 03:39:552591 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032592 glGenFramebuffersEXT(n, service_ids.get());
2593 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352594 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032595 }
2596 return true;
2597}
2598
2599bool GLES2DecoderImpl::GenRenderbuffersHelper(
2600 GLsizei n, const GLuint* client_ids) {
2601 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352602 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032603 return false;
2604 }
2605 }
[email protected]40d90a22013-04-09 03:39:552606 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032607 glGenRenderbuffersEXT(n, service_ids.get());
2608 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352609 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032610 }
2611 return true;
2612}
2613
2614bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2615 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352616 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032617 return false;
2618 }
2619 }
[email protected]40d90a22013-04-09 03:39:552620 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032621 glGenTextures(n, service_ids.get());
2622 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352623 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032624 }
2625 return true;
2626}
2627
2628void GLES2DecoderImpl::DeleteBuffersHelper(
2629 GLsizei n, const GLuint* client_ids) {
2630 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212631 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102632 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242633 state_.vertex_attrib_manager->Unbind(buffer);
2634 if (state_.bound_array_buffer == buffer) {
2635 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102636 }
[email protected]ed9f9cd2013-02-27 21:12:352637 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032638 }
[email protected]a93bb842010-02-16 23:03:472639 }
[email protected]07f54fcc2009-12-22 02:46:302640}
2641
[email protected]ae51d192010-04-27 00:48:032642void GLES2DecoderImpl::DeleteFramebuffersHelper(
2643 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452644 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152645 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112646
[email protected]a25fa872010-03-25 02:57:582647 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352648 Framebuffer* framebuffer =
2649 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102650 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242651 if (framebuffer == state_.bound_draw_framebuffer) {
2652 state_.bound_draw_framebuffer = NULL;
[email protected]88a61bf2012-10-27 13:00:422653 clear_state_dirty_ = true;
[email protected]ebfb73c2012-08-15 02:37:452654 GLenum target = supports_separate_framebuffer_binds ?
2655 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112656 glBindFramebufferEXT(target, GetBackbufferServiceId());
2657 }
[email protected]e259eb412012-10-13 05:47:242658 if (framebuffer == state_.bound_read_framebuffer) {
2659 state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452660 GLenum target = supports_separate_framebuffer_binds ?
2661 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112662 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462663 }
[email protected]70d34263c2013-01-09 00:27:452664 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352665 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032666 }
[email protected]a25fa872010-03-25 02:57:582667 }
[email protected]07f54fcc2009-12-22 02:46:302668}
2669
[email protected]ae51d192010-04-27 00:48:032670void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2671 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452672 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152673 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582674 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352675 Renderbuffer* renderbuffer =
2676 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102677 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242678 if (state_.bound_renderbuffer == renderbuffer) {
2679 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102680 }
2681 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452682 if (supports_separate_framebuffer_binds) {
[email protected]e259eb412012-10-13 05:47:242683 if (state_.bound_read_framebuffer) {
2684 state_.bound_read_framebuffer->UnbindRenderbuffer(
[email protected]ebfb73c2012-08-15 02:37:452685 GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102686 }
[email protected]e259eb412012-10-13 05:47:242687 if (state_.bound_draw_framebuffer) {
2688 state_.bound_draw_framebuffer->UnbindRenderbuffer(
[email protected]ebfb73c2012-08-15 02:37:452689 GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102690 }
2691 } else {
[email protected]e259eb412012-10-13 05:47:242692 if (state_.bound_draw_framebuffer) {
2693 state_.bound_draw_framebuffer->UnbindRenderbuffer(
[email protected]a0b78dc2011-11-11 10:43:102694 GL_FRAMEBUFFER, renderbuffer);
2695 }
2696 }
[email protected]88a61bf2012-10-27 13:00:422697 clear_state_dirty_ = true;
[email protected]ed9f9cd2013-02-27 21:12:352698 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032699 }
[email protected]a25fa872010-03-25 02:57:582700 }
[email protected]07f54fcc2009-12-22 02:46:302701}
2702
[email protected]ae51d192010-04-27 00:48:032703void GLES2DecoderImpl::DeleteTexturesHelper(
2704 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452705 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152706 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472707 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:492708 TextureRef* texture_ref = GetTexture(client_ids[ii]);
2709 if (texture_ref) {
2710 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:102711 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:422712 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462713 }
[email protected]370eaf12013-05-18 09:19:492714 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:022715 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:492716 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102717 }
2718 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452719 if (supports_separate_framebuffer_binds) {
[email protected]e259eb412012-10-13 05:47:242720 if (state_.bound_read_framebuffer) {
2721 state_.bound_read_framebuffer->UnbindTexture(
[email protected]370eaf12013-05-18 09:19:492722 GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102723 }
[email protected]e259eb412012-10-13 05:47:242724 if (state_.bound_draw_framebuffer) {
2725 state_.bound_draw_framebuffer->UnbindTexture(
[email protected]370eaf12013-05-18 09:19:492726 GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102727 }
2728 } else {
[email protected]e259eb412012-10-13 05:47:242729 if (state_.bound_draw_framebuffer) {
[email protected]370eaf12013-05-18 09:19:492730 state_.bound_draw_framebuffer->UnbindTexture(GL_FRAMEBUFFER,
2731 texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102732 }
2733 }
2734 GLuint service_id = texture->service_id();
2735 if (texture->IsStreamTexture() && stream_texture_manager_) {
[email protected]b0af4f52011-09-28 22:04:422736 stream_texture_manager_->DestroyStreamTexture(service_id);
2737 }
[email protected]e51bdf32011-11-23 22:21:462738#if defined(OS_MACOSX)
2739 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
2740 ReleaseIOSurfaceForTexture(service_id);
2741 }
2742#endif
[email protected]ed9f9cd2013-02-27 21:12:352743 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032744 }
[email protected]a93bb842010-02-16 23:03:472745 }
[email protected]07f54fcc2009-12-22 02:46:302746}
2747
[email protected]43f28f832010-02-03 02:28:482748// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:322749
[email protected]eb54a562010-01-20 21:55:182750bool GLES2DecoderImpl::MakeCurrent() {
[email protected]63c9b052012-05-17 18:27:382751 if (!context_.get() || !context_->MakeCurrent(surface_.get()))
2752 return false;
2753
2754 if (WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:432755 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:292756
2757 // Some D3D drivers cannot recover from device lost in the GPU process
2758 // sandbox. Allow a new GPU process to launch.
2759 if (workarounds().exit_on_context_lost) {
2760 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
2761 << " a D3D device in the Chrome GPU process sandbox.";
2762 exit(0);
2763 }
2764
[email protected]63c9b052012-05-17 18:27:382765 return false;
[email protected]38d139d2011-07-14 00:38:432766 }
2767
[email protected]69a8701e2013-03-07 21:31:092768 ProcessFinishedAsyncTransfers();
2769 if (workarounds().flush_on_context_switch)
2770 glFlush();
2771
[email protected]9b753992013-04-27 02:04:412772 // Rebind the FBO if it was unbound by the context.
2773 if (workarounds().unbind_fbo_on_context_switch)
2774 RestoreFramebufferBindings();
2775
[email protected]370eaf12013-05-18 09:19:492776 clear_state_dirty_ = true;
2777
[email protected]69a8701e2013-03-07 21:31:092778 return true;
2779}
2780
2781void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]fe8d73c2013-02-16 22:37:322782 if (engine() && query_manager_.get())
2783 query_manager_->ProcessPendingTransferQueries();
2784
[email protected]5b3a8e02013-03-13 05:36:442785 // TODO(epenner): Is there a better place to do this?
2786 // This needs to occur before we execute any batch of commands
2787 // from the client, as the client may have recieved an async
2788 // completion while issuing those commands.
2789 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b75ff642013-05-09 05:30:292790 async_pixel_transfer_delegate_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:182791}
2792
[email protected]a96a6022011-11-04 00:58:122793void GLES2DecoderImpl::ReleaseCurrent() {
2794 if (context_.get())
2795 context_->ReleaseCurrent(surface_.get());
2796}
2797
[email protected]8e3e0662010-08-23 18:46:302798void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() {
[email protected]ed9f9cd2013-02-27 21:12:352799 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:202800 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
[email protected]8e3e0662010-08-23 18:46:302801 glBindRenderbufferEXT(
[email protected]0d6bfdc2011-11-02 01:32:202802 GL_RENDERBUFFER, renderbuffer ? renderbuffer->service_id() : 0);
[email protected]8e3e0662010-08-23 18:46:302803}
2804
2805static void RebindCurrentFramebuffer(
2806 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:062807 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:242808 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:062809 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:462810
[email protected]a3783712012-01-20 22:18:242811 if (framebuffer_id == 0) {
2812 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:302813 }
[email protected]297ca1c2011-06-20 23:08:462814
[email protected]8e3e0662010-08-23 18:46:302815 glBindFramebufferEXT(target, framebuffer_id);
2816}
2817
2818void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]88a61bf2012-10-27 13:00:422819 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462820
[email protected]62e155e2012-10-23 22:43:152821 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:302822 RebindCurrentFramebuffer(
2823 GL_FRAMEBUFFER,
[email protected]e259eb412012-10-13 05:47:242824 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242825 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302826 } else {
2827 RebindCurrentFramebuffer(
2828 GL_READ_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242829 state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242830 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302831 RebindCurrentFramebuffer(
2832 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242833 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242834 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302835 }
[email protected]70d34263c2013-01-09 00:27:452836 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:302837}
2838
2839void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() {
[email protected]e259eb412012-10-13 05:47:242840 TextureUnit& info = state_.texture_units[0];
[email protected]8e3e0662010-08-23 18:46:302841 GLuint last_id;
2842 if (info.bound_texture_2d) {
2843 last_id = info.bound_texture_2d->service_id();
2844 } else {
2845 last_id = 0;
2846 }
2847
2848 glBindTexture(GL_TEXTURE_2D, last_id);
[email protected]e259eb412012-10-13 05:47:242849 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]8e3e0662010-08-23 18:46:302850}
2851
[email protected]0d6bfdc2011-11-02 01:32:202852bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:352853 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:202854 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:102855 if (!framebuffer) {
[email protected]60f22d32012-12-12 00:31:582856 if (backbuffer_needs_clear_bits_) {
2857 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
2858 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
2859 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2860 glClearStencil(0);
2861 glStencilMask(-1);
2862 glClearDepth(1.0f);
2863 glDepthMask(true);
2864 glDisable(GL_SCISSOR_TEST);
2865 glClear(backbuffer_needs_clear_bits_);
2866 backbuffer_needs_clear_bits_ = 0;
2867 RestoreClearState();
2868 }
[email protected]0d6bfdc2011-11-02 01:32:202869 return true;
2870 }
2871
[email protected]968351b2011-12-20 08:26:512872 if (framebuffer_manager()->IsComplete(framebuffer)) {
2873 return true;
2874 }
2875
[email protected]0d6bfdc2011-11-02 01:32:202876 GLenum completeness = framebuffer->IsPossiblyComplete();
2877 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512878 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432879 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:272880 return false;
2881 }
[email protected]0d6bfdc2011-11-02 01:32:202882
2883 // Are all the attachments cleared?
2884 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
2885 texture_manager()->HaveUnclearedMips()) {
2886 if (!framebuffer->IsCleared()) {
2887 // Can we clear them?
[email protected]73276522012-11-09 05:50:202888 if (framebuffer->GetStatus(texture_manager(), target) !=
2889 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512890 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432891 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2892 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:202893 return false;
2894 }
2895 ClearUnclearedAttachments(target, framebuffer);
2896 }
2897 }
2898
[email protected]968351b2011-12-20 08:26:512899 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:202900 if (framebuffer->GetStatus(texture_manager(), target) !=
2901 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512902 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432903 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2904 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:512905 return false;
2906 }
2907 framebuffer_manager()->MarkAsComplete(framebuffer);
2908 }
2909
[email protected]0d6bfdc2011-11-02 01:32:202910 // NOTE: At this point we don't know if the framebuffer is complete but
2911 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:272912 return true;
2913}
2914
[email protected]0d6bfdc2011-11-02 01:32:202915bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:152916 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:512917 bool valid = CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242918 state_.bound_draw_framebuffer, GL_FRAMEBUFFER_EXT, func_name);
[email protected]28718a92013-04-04 12:12:512919
2920 if (valid)
2921 OnUseFramebuffer();
2922
2923 return valid;
[email protected]0d6bfdc2011-11-02 01:32:202924 }
2925 return CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242926 state_.bound_draw_framebuffer,
2927 GL_DRAW_FRAMEBUFFER_EXT, func_name) &&
[email protected]0d6bfdc2011-11-02 01:32:202928 CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242929 state_.bound_read_framebuffer,
2930 GL_READ_FRAMEBUFFER_EXT, func_name);
[email protected]0d6bfdc2011-11-02 01:32:202931}
2932
[email protected]8e3e0662010-08-23 18:46:302933gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:352934 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452935 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202936 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:352937 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:202938 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:262939 if (attachment) {
2940 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:502941 }
[email protected]9edc6b22010-12-23 02:00:262942 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:022943 } else if (offscreen_target_frame_buffer_.get()) {
2944 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:352945 } else {
[email protected]f62a5ab2011-05-23 20:34:152946 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:022947 }
[email protected]246a70452010-03-05 21:53:502948}
2949
[email protected]9edc6b22010-12-23 02:00:262950GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:352951 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452952 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202953 if (framebuffer != NULL) {
2954 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:462955 } else if (offscreen_target_frame_buffer_.get()) {
2956 return offscreen_target_color_format_;
2957 } else {
2958 return back_buffer_color_format_;
2959 }
2960}
2961
2962GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:352963 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452964 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202965 if (framebuffer != NULL) {
2966 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:262967 } else if (offscreen_target_frame_buffer_.get()) {
2968 return offscreen_target_color_format_;
2969 } else {
[email protected]32fe9aa2011-01-21 23:47:132970 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:262971 }
2972}
2973
[email protected]9a5afa432011-07-22 18:16:392974void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]34ff8b0c2010-10-01 20:06:022975 if (parent_) {
[email protected]2f2d7042010-04-14 21:45:582976 // Update the info about the offscreen saved color texture in the parent.
2977 // The reference to the parent is a weak pointer and will become null if the
2978 // parent is later destroyed.
[email protected]370eaf12013-05-18 09:19:492979 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
[email protected]262d7aa2010-12-03 22:07:292980 TextureManager* parent_texture_manager = parent_->texture_manager();
[email protected]370eaf12013-05-18 09:19:492981 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
[email protected]262d7aa2010-12-03 22:07:292982 parent_texture_manager->SetLevelInfo(
[email protected]8a61d872012-01-20 12:43:562983 offscreen_saved_color_texture_info_,
[email protected]ef526492010-06-02 23:12:252984 GL_TEXTURE_2D,
2985 0, // level
2986 GL_RGBA,
[email protected]799b4b22011-08-22 17:09:592987 offscreen_size_.width(),
2988 offscreen_size_.height(),
[email protected]ef526492010-06-02 23:12:252989 1, // depth
2990 0, // border
2991 GL_RGBA,
[email protected]0d6bfdc2011-11-02 01:32:202992 GL_UNSIGNED_BYTE,
2993 true);
[email protected]262d7aa2010-12-03 22:07:292994 parent_texture_manager->SetParameter(
[email protected]02965c22013-03-09 02:40:072995 "UpdateParentTextureInfo",
[email protected]d3eba342013-04-18 21:11:502996 GetErrorState(),
[email protected]8a61d872012-01-20 12:43:562997 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:042998 GL_TEXTURE_MAG_FILTER,
2999 GL_NEAREST);
[email protected]262d7aa2010-12-03 22:07:293000 parent_texture_manager->SetParameter(
[email protected]02965c22013-03-09 02:40:073001 "UpdateParentTextureInfo",
[email protected]d3eba342013-04-18 21:11:503002 GetErrorState(),
[email protected]8a61d872012-01-20 12:43:563003 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:043004 GL_TEXTURE_MIN_FILTER,
3005 GL_NEAREST);
[email protected]262d7aa2010-12-03 22:07:293006 parent_texture_manager->SetParameter(
[email protected]02965c22013-03-09 02:40:073007 "UpdateParentTextureInfo",
[email protected]d3eba342013-04-18 21:11:503008 GetErrorState(),
[email protected]8a61d872012-01-20 12:43:563009 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:043010 GL_TEXTURE_WRAP_S,
3011 GL_CLAMP_TO_EDGE);
[email protected]262d7aa2010-12-03 22:07:293012 parent_texture_manager->SetParameter(
[email protected]02965c22013-03-09 02:40:073013 "UpdateParentTextureInfo",
[email protected]d3eba342013-04-18 21:11:503014 GetErrorState(),
[email protected]8a61d872012-01-20 12:43:563015 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:043016 GL_TEXTURE_WRAP_T,
3017 GL_CLAMP_TO_EDGE);
[email protected]370eaf12013-05-18 09:19:493018 TextureRef* texture_ref = GetTextureInfoForTarget(target);
3019 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]8a61d872012-01-20 12:43:563020 } else {
3021 offscreen_saved_color_texture_info_ = NULL;
[email protected]0c8c9d22010-06-25 17:36:393022 }
[email protected]6217d392010-03-25 22:08:353023}
3024
[email protected]799b4b22011-08-22 17:09:593025void GLES2DecoderImpl::SetResizeCallback(
[email protected]9d37f062011-11-22 01:24:523026 const base::Callback<void(gfx::Size)>& callback) {
3027 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003028}
3029
[email protected]1d82e822013-04-10 21:32:323030Logger* GLES2DecoderImpl::GetLogger() {
3031 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523032}
3033
[email protected]d3eba342013-04-18 21:11:503034ErrorState* GLES2DecoderImpl::GetErrorState() {
3035 return state_.GetErrorState();
3036}
3037
[email protected]e3932abb2013-03-13 00:01:373038void GLES2DecoderImpl::SetShaderCacheCallback(
3039 const ShaderCacheCallback& callback) {
3040 shader_cache_callback_ = callback;
3041}
3042
[email protected]840a7e462013-02-27 01:29:513043void GLES2DecoderImpl::SetWaitSyncPointCallback(
3044 const WaitSyncPointCallback& callback) {
3045 wait_sync_point_callback_ = callback;
3046}
3047
[email protected]b0af4f52011-09-28 22:04:423048void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) {
3049 stream_texture_manager_ = manager;
3050}
3051
[email protected]2a7568a2013-05-09 23:12:033052AsyncPixelTransferDelegate*
[email protected]32145a92012-12-17 09:01:593053 GLES2DecoderImpl::GetAsyncPixelTransferDelegate() {
3054 return async_pixel_transfer_delegate_.get();
3055}
3056
3057void GLES2DecoderImpl::SetAsyncPixelTransferDelegate(
[email protected]2a7568a2013-05-09 23:12:033058 AsyncPixelTransferDelegate* delegate) {
[email protected]32145a92012-12-17 09:01:593059 async_pixel_transfer_delegate_ = make_scoped_ptr(delegate);
3060}
3061
[email protected]1318e922010-09-17 22:03:163062bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3063 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493064 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3065 if (texture_ref) {
3066 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163067 return true;
3068 }
3069 return false;
3070}
3071
[email protected]63b465922012-09-06 02:04:523072uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]b9804322013-01-08 17:54:123073 return texture_upload_count_ +
3074 async_pixel_transfer_delegate_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523075}
3076
3077base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]b9804322013-01-08 17:54:123078 return total_texture_upload_time_ +
3079 async_pixel_transfer_delegate_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523080}
3081
3082base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3083 return total_processing_commands_time_;
3084}
3085
[email protected]dc25dda2012-09-27 21:36:303086void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3087 total_processing_commands_time_ += time;
3088}
3089
[email protected]63c9b052012-05-17 18:27:383090void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063091 if (!initialized())
3092 return;
3093
[email protected]63c9b052012-05-17 18:27:383094 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053095
[email protected]c826d732012-02-09 04:40:263096 ChildList children = children_;
3097 for (ChildList::iterator it = children.begin(); it != children.end(); ++it)
3098 (*it)->SetParent(NULL, 0);
3099 DCHECK(children_.empty());
[email protected]3c644d82011-06-20 19:58:243100 SetParent(NULL, 0);
3101
[email protected]80eb6b52012-01-19 00:14:413102 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243103 state_.vertex_attrib_manager = NULL;
[email protected]944b62f32012-09-27 02:20:463104 default_vertex_attrib_manager_ = NULL;
[email protected]1868a342012-11-07 15:56:023105 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243106 state_.bound_array_buffer = NULL;
3107 state_.current_query = NULL;
3108 state_.current_program = NULL;
3109 state_.bound_read_framebuffer = NULL;
3110 state_.bound_draw_framebuffer = NULL;
3111 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413112
[email protected]eadc96792010-10-27 19:39:393113 if (have_context) {
[email protected]c322e882012-05-23 18:06:183114 if (copy_texture_CHROMIUM_.get()) {
3115 copy_texture_CHROMIUM_->Destroy();
3116 copy_texture_CHROMIUM_.reset();
3117 }
[email protected]43410e92012-04-20 17:06:283118
[email protected]e259eb412012-10-13 05:47:243119 if (state_.current_program) {
3120 program_manager()->UnuseProgram(shader_manager(), state_.current_program);
3121 state_.current_program = NULL;
[email protected]ca488e12010-12-13 20:06:143122 }
3123
[email protected]b1122982010-05-17 23:04:243124 if (attrib_0_buffer_id_) {
3125 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3126 }
[email protected]8fbedc02010-11-18 18:43:403127 if (fixed_attrib_buffer_id_) {
3128 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3129 }
[email protected]b1122982010-05-17 23:04:243130
[email protected]97872062010-11-03 19:07:053131 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543132 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053133 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543134 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053135 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023136 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053137 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153138 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053139 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153140 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053141 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023142 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053143 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543144 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273145 if (offscreen_resolved_frame_buffer_.get())
3146 offscreen_resolved_frame_buffer_->Destroy();
3147 if (offscreen_resolved_color_texture_.get())
3148 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053149 } else {
3150 if (offscreen_target_frame_buffer_.get())
3151 offscreen_target_frame_buffer_->Invalidate();
3152 if (offscreen_target_color_texture_.get())
3153 offscreen_target_color_texture_->Invalidate();
3154 if (offscreen_target_color_render_buffer_.get())
3155 offscreen_target_color_render_buffer_->Invalidate();
3156 if (offscreen_target_depth_render_buffer_.get())
3157 offscreen_target_depth_render_buffer_->Invalidate();
3158 if (offscreen_target_stencil_render_buffer_.get())
3159 offscreen_target_stencil_render_buffer_->Invalidate();
3160 if (offscreen_saved_frame_buffer_.get())
3161 offscreen_saved_frame_buffer_->Invalidate();
3162 if (offscreen_saved_color_texture_.get())
3163 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273164 if (offscreen_resolved_frame_buffer_.get())
3165 offscreen_resolved_frame_buffer_->Invalidate();
3166 if (offscreen_resolved_color_texture_.get())
3167 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023168 }
[email protected]43410e92012-04-20 17:06:283169 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053170
[email protected]882ba1e22012-03-08 19:02:533171 if (query_manager_.get()) {
3172 query_manager_->Destroy(have_context);
3173 query_manager_.reset();
3174 }
3175
[email protected]944b62f32012-09-27 02:20:463176 if (vertex_array_manager_ .get()) {
3177 vertex_array_manager_->Destroy(have_context);
3178 vertex_array_manager_.reset();
3179 }
3180
[email protected]97872062010-11-03 19:07:053181 offscreen_target_frame_buffer_.reset();
3182 offscreen_target_color_texture_.reset();
3183 offscreen_target_color_render_buffer_.reset();
3184 offscreen_target_depth_render_buffer_.reset();
3185 offscreen_target_stencil_render_buffer_.reset();
3186 offscreen_saved_frame_buffer_.reset();
3187 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273188 offscreen_resolved_frame_buffer_.reset();
3189 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463190
[email protected]2d9d3b92013-01-18 01:07:233191 if (group_) {
3192 group_->Destroy(this, have_context);
3193 group_ = NULL;
3194 }
3195
3196 if (context_.get()) {
3197 context_->ReleaseCurrent(NULL);
3198 context_ = NULL;
3199 }
3200
[email protected]e51bdf32011-11-23 22:21:463201#if defined(OS_MACOSX)
3202 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3203 it != texture_to_io_surface_map_.end(); ++it) {
3204 CFRelease(it->second);
3205 }
3206 texture_to_io_surface_map_.clear();
3207#endif
[email protected]96449d2c2009-11-25 00:01:323208}
3209
[email protected]63c9b052012-05-17 18:27:383210void GLES2DecoderImpl::SetSurface(
3211 const scoped_refptr<gfx::GLSurface>& surface) {
3212 DCHECK(context_->IsCurrent(NULL));
3213 DCHECK(surface_.get());
3214 surface_ = surface;
3215 RestoreCurrentFramebufferBindings();
3216}
3217
[email protected]3c644d82011-06-20 19:58:243218bool GLES2DecoderImpl::SetParent(GLES2Decoder* new_parent,
3219 uint32 new_parent_texture_id) {
[email protected]9a5afa432011-07-22 18:16:393220 if (!offscreen_saved_color_texture_.get())
3221 return false;
3222
[email protected]3c644d82011-06-20 19:58:243223 // Remove the saved frame buffer mapping from the parent decoder. The
3224 // parent pointer is a weak pointer so it will be null if the parent has
3225 // already been destroyed.
3226 if (parent_) {
[email protected]c826d732012-02-09 04:40:263227 ChildList::iterator it = std::find(
3228 parent_->children_.begin(),
3229 parent_->children_.end(),
3230 this);
3231 DCHECK(it != parent_->children_.end());
3232 parent_->children_.erase(it);
[email protected]3c644d82011-06-20 19:58:243233 // First check the texture has been mapped into the parent. This might not
3234 // be the case if initialization failed midway through.
3235 GLuint service_id = offscreen_saved_color_texture_->id();
3236 GLuint client_id = 0;
3237 if (parent_->texture_manager()->GetClientId(service_id, &client_id)) {
[email protected]ed9f9cd2013-02-27 21:12:353238 parent_->texture_manager()->RemoveTexture(client_id);
[email protected]3c644d82011-06-20 19:58:243239 }
3240 }
3241
3242 GLES2DecoderImpl* new_parent_impl = static_cast<GLES2DecoderImpl*>(
3243 new_parent);
3244 if (new_parent_impl) {
[email protected]c826d732012-02-09 04:40:263245#ifndef NDEBUG
3246 ChildList::iterator it = std::find(
3247 new_parent_impl->children_.begin(),
3248 new_parent_impl->children_.end(),
3249 this);
3250 DCHECK(it == new_parent_impl->children_.end());
3251#endif
3252 new_parent_impl->children_.push_back(this);
[email protected]3c644d82011-06-20 19:58:243253 // Map the ID of the saved offscreen texture into the parent so that
3254 // it can reference it.
3255 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]98687862011-07-11 23:31:303256
3257 // Replace texture info when ID is already in use by parent.
[email protected]ed9f9cd2013-02-27 21:12:353258 if (new_parent_impl->texture_manager()->GetTexture(
[email protected]80eb6b52012-01-19 00:14:413259 new_parent_texture_id))
[email protected]ed9f9cd2013-02-27 21:12:353260 new_parent_impl->texture_manager()->RemoveTexture(
[email protected]80eb6b52012-01-19 00:14:413261 new_parent_texture_id);
[email protected]98687862011-07-11 23:31:303262
[email protected]8a61d872012-01-20 12:43:563263 offscreen_saved_color_texture_info_ =
[email protected]ed9f9cd2013-02-27 21:12:353264 new_parent_impl->CreateTexture(new_parent_texture_id, service_id);
[email protected]370eaf12013-05-18 09:19:493265 offscreen_saved_color_texture_info_->texture()->SetNotOwned();
[email protected]8a61d872012-01-20 12:43:563266 new_parent_impl->texture_manager()->
[email protected]02965c22013-03-09 02:40:073267 SetTarget(offscreen_saved_color_texture_info_, GL_TEXTURE_2D);
[email protected]3c644d82011-06-20 19:58:243268
[email protected]ee1e6aa2012-11-29 09:24:103269 parent_ = base::AsWeakPtr<GLES2DecoderImpl>(new_parent_impl);
[email protected]9a5afa432011-07-22 18:16:393270
3271 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243272 } else {
3273 parent_.reset();
[email protected]8a61d872012-01-20 12:43:563274 offscreen_saved_color_texture_info_ = NULL;
[email protected]3c644d82011-06-20 19:58:243275 }
3276
3277 return true;
3278}
3279
[email protected]260ddc4e2012-06-28 00:01:533280size_t GLES2DecoderImpl::GetBackbufferMemoryTotal() {
[email protected]1078f912011-12-23 13:12:143281 size_t total = 0;
3282 if (offscreen_target_frame_buffer_.get()) {
3283 if (offscreen_target_color_texture_.get()) {
3284 total += offscreen_target_color_texture_->estimated_size();
3285 }
3286 if (offscreen_target_color_render_buffer_.get()) {
3287 total += offscreen_target_color_render_buffer_->estimated_size();
3288 }
3289 if (offscreen_target_depth_render_buffer_.get()) {
3290 total += offscreen_target_depth_render_buffer_->estimated_size();
3291 }
3292 if (offscreen_target_stencil_render_buffer_.get()) {
3293 total += offscreen_target_stencil_render_buffer_->estimated_size();
3294 }
3295 if (offscreen_saved_color_texture_.get()) {
3296 total += offscreen_saved_color_texture_->estimated_size();
3297 }
3298 if (offscreen_resolved_color_texture_.get()) {
3299 total += offscreen_resolved_color_texture_->estimated_size();
3300 }
3301 } else {
3302 gfx::Size size = surface_->GetSize();
3303 total += size.width() * size.height() *
3304 GLES2Util::RenderbufferBytesPerPixel(back_buffer_color_format_);
3305 }
[email protected]260ddc4e2012-06-28 00:01:533306 return total;
[email protected]1078f912011-12-23 13:12:143307}
3308
[email protected]799b4b22011-08-22 17:09:593309bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3310 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3311 if (!is_offscreen) {
3312 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3313 << " with an onscreen framebuffer.";
3314 return false;
3315 }
3316
3317 if (offscreen_size_ == size)
3318 return true;
3319
3320 offscreen_size_ = size;
3321 int w = offscreen_size_.width();
3322 int h = offscreen_size_.height();
3323 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3324 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3325 << "to allocate storage due to excessive dimensions.";
3326 return false;
3327 }
3328
3329 // Reallocate the offscreen target buffers.
3330 DCHECK(offscreen_target_color_format_);
3331 if (IsOffscreenBufferMultisampled()) {
3332 if (!offscreen_target_color_render_buffer_->AllocateStorage(
3333 offscreen_size_, offscreen_target_color_format_,
3334 offscreen_target_samples_)) {
3335 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3336 << "to allocate storage for offscreen target color buffer.";
3337 return false;
3338 }
3339 } else {
3340 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093341 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593342 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3343 << "to allocate storage for offscreen target color texture.";
3344 return false;
3345 }
3346 }
3347 if (offscreen_target_depth_format_ &&
3348 !offscreen_target_depth_render_buffer_->AllocateStorage(
3349 offscreen_size_, offscreen_target_depth_format_,
3350 offscreen_target_samples_)) {
3351 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3352 << "to allocate storage for offscreen target depth buffer.";
3353 return false;
3354 }
3355 if (offscreen_target_stencil_format_ &&
3356 !offscreen_target_stencil_render_buffer_->AllocateStorage(
3357 offscreen_size_, offscreen_target_stencil_format_,
3358 offscreen_target_samples_)) {
3359 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3360 << "to allocate storage for offscreen target stencil buffer.";
3361 return false;
3362 }
3363
3364 // Attach the offscreen target buffers to the target frame buffer.
3365 if (IsOffscreenBufferMultisampled()) {
3366 offscreen_target_frame_buffer_->AttachRenderBuffer(
3367 GL_COLOR_ATTACHMENT0,
3368 offscreen_target_color_render_buffer_.get());
3369 } else {
3370 offscreen_target_frame_buffer_->AttachRenderTexture(
3371 offscreen_target_color_texture_.get());
3372 }
3373 if (offscreen_target_depth_format_) {
3374 offscreen_target_frame_buffer_->AttachRenderBuffer(
3375 GL_DEPTH_ATTACHMENT,
3376 offscreen_target_depth_render_buffer_.get());
3377 }
3378 const bool packed_depth_stencil =
3379 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3380 if (packed_depth_stencil) {
3381 offscreen_target_frame_buffer_->AttachRenderBuffer(
3382 GL_STENCIL_ATTACHMENT,
3383 offscreen_target_depth_render_buffer_.get());
3384 } else if (offscreen_target_stencil_format_) {
3385 offscreen_target_frame_buffer_->AttachRenderBuffer(
3386 GL_STENCIL_ATTACHMENT,
3387 offscreen_target_stencil_render_buffer_.get());
3388 }
3389
3390 if (offscreen_target_frame_buffer_->CheckStatus() !=
3391 GL_FRAMEBUFFER_COMPLETE) {
3392 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3393 << "because offscreen FBO was incomplete.";
3394 return false;
3395 }
3396
3397 // Clear the target frame buffer.
3398 {
3399 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3400 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3401 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3402 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3403 glClearStencil(0);
3404 glStencilMaskSeparate(GL_FRONT, -1);
3405 glStencilMaskSeparate(GL_BACK, -1);
3406 glClearDepth(0);
3407 glDepthMask(GL_TRUE);
3408 glDisable(GL_SCISSOR_TEST);
3409 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3410 RestoreClearState();
3411 }
[email protected]d85ef76d2011-09-08 22:21:433412
3413 // Destroy the offscreen resolved framebuffers.
3414 if (offscreen_resolved_frame_buffer_.get())
3415 offscreen_resolved_frame_buffer_->Destroy();
3416 if (offscreen_resolved_color_texture_.get())
3417 offscreen_resolved_color_texture_->Destroy();
3418 offscreen_resolved_color_texture_.reset();
3419 offscreen_resolved_frame_buffer_.reset();
3420
[email protected]799b4b22011-08-22 17:09:593421 return true;
[email protected]6217d392010-03-25 22:08:353422}
3423
[email protected]799b4b22011-08-22 17:09:593424error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:353425 uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) {
[email protected]09e17272012-11-30 10:30:443426 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023427 return error::kDeferCommandUntilLater;
3428
[email protected]799b4b22011-08-22 17:09:593429 GLuint width = static_cast<GLuint>(c.width);
3430 GLuint height = static_cast<GLuint>(c.height);
3431 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413432
3433 width = std::max(1U, width);
3434 height = std::max(1U, height);
3435
[email protected]a0d989162011-11-22 13:15:073436#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3437 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003438 // Make sure that we are done drawing to the back buffer before resizing.
3439 glFinish();
3440#endif
[email protected]799b4b22011-08-22 17:09:593441 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3442 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493443 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3444 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3445 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593446 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493447 }
[email protected]7ff86b92010-11-25 17:50:003448 }
[email protected]799b4b22011-08-22 17:09:593449
[email protected]9d37f062011-11-22 01:24:523450 if (!resize_callback_.is_null()) {
3451 resize_callback_.Run(gfx::Size(width, height));
[email protected]0e9346b2013-03-16 16:35:443452 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493453 if (!context_->IsCurrent(surface_.get())) {
3454 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3455 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053456 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493457 }
[email protected]658f7562011-09-09 05:24:053458 }
[email protected]799b4b22011-08-22 17:09:593459
3460 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393461}
3462
[email protected]96449d2c2009-11-25 00:01:323463const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3464 if (command_id > kStartPoint && command_id < kNumCommands) {
3465 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3466 }
3467 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3468}
3469
3470// Decode command with its arguments, and call the corresponding GL function.
3471// Note: args is a pointer to the command buffer. As such, it could be changed
3472// by a (malicious) client at any time, so if validation has to happen, it
3473// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143474error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323475 unsigned int command,
3476 unsigned int arg_count,
3477 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143478 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263479 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003480 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
3481 // LOG(INFO), tried VLOG(1), no luck.
[email protected]1d82e822013-04-10 21:32:323482 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" << "cmd: "
[email protected]d2a0e1a2012-08-12 02:25:013483 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193484 }
[email protected]96449d2c2009-11-25 00:01:323485 unsigned int command_index = command - kStartPoint - 1;
3486 if (command_index < arraysize(g_command_info)) {
3487 const CommandInfo& info = g_command_info[command_index];
3488 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3489 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3490 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]b9849abf2009-11-25 19:13:193491 uint32 immediate_data_size =
3492 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323493 switch (command) {
3494 #define GLES2_CMD_OP(name) \
[email protected]ed9f9cd2013-02-27 21:12:353495 case cmds::name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193496 result = Handle ## name( \
3497 immediate_data_size, \
[email protected]ed9f9cd2013-02-27 21:12:353498 *static_cast<const gles2::cmds::name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193499 break; \
[email protected]96449d2c2009-11-25 00:01:323500
3501 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323502 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383503 }
3504 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303505 GLenum error;
3506 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]1d82e822013-04-10 21:32:323507 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003508 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3509 << GetCommandName(command);
[email protected]ab09b612013-03-11 22:11:513510 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193511 }
[email protected]96449d2c2009-11-25 00:01:323512 }
3513 } else {
[email protected]f7a64ee2010-02-01 22:24:143514 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323515 }
[email protected]b9849abf2009-11-25 19:13:193516 } else {
3517 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323518 }
[email protected]a3a93e7b2010-08-28 00:48:563519 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3520 result = current_decoder_error_;
3521 current_decoder_error_ = error::kNoError;
3522 }
[email protected]b9849abf2009-11-25 19:13:193523 return result;
[email protected]96449d2c2009-11-25 00:01:323524}
3525
[email protected]ed9f9cd2013-02-27 21:12:353526void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3527 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503528}
3529
[email protected]ae51d192010-04-27 00:48:033530bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353531 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033532 return false;
3533 }
[email protected]96449d2c2009-11-25 00:01:323534 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033535 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353536 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323537 }
[email protected]ae51d192010-04-27 00:48:033538 return true;
[email protected]96449d2c2009-11-25 00:01:323539}
3540
[email protected]ae51d192010-04-27 00:48:033541bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353542 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033543 return false;
[email protected]96449d2c2009-11-25 00:01:323544 }
[email protected]ae51d192010-04-27 00:48:033545 GLuint service_id = glCreateShader(type);
3546 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353547 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033548 }
3549 return true;
[email protected]96449d2c2009-11-25 00:01:323550}
3551
[email protected]882ba1e22012-03-08 19:02:533552void GLES2DecoderImpl::DoFinish() {
3553 glFinish();
[email protected]22e3f552012-03-13 01:54:193554 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533555}
3556
3557void GLES2DecoderImpl::DoFlush() {
3558 glFlush();
[email protected]22e3f552012-03-13 01:54:193559 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533560}
3561
[email protected]3916c97e2010-02-25 03:20:503562void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453563 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023564 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513565 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533566 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503567 return;
3568 }
[email protected]e259eb412012-10-13 05:47:243569 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453570 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503571}
3572
[email protected]051b1372010-04-12 02:42:083573void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073574 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083575 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033576 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073577 buffer = GetBuffer(client_id);
3578 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353579 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153580 LOG(ERROR) << "glBindBuffer: id not generated by glGenBuffers";
3581 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353582 return;
3583 }
3584
[email protected]b10492f2013-03-08 05:24:073585 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033586 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353587 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073588 buffer = GetBuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573589 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103590 group_->GetIdAllocator(id_namespaces::kBuffers);
3591 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033592 }
[email protected]051b1372010-04-12 02:42:083593 }
[email protected]b10492f2013-03-08 05:24:073594 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3595 if (buffer) {
3596 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513597 LOCAL_SET_GL_ERROR(
3598 GL_INVALID_OPERATION,
3599 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473600 return;
3601 }
[email protected]b10492f2013-03-08 05:24:073602 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473603 }
[email protected]96449d2c2009-11-25 00:01:323604 switch (target) {
3605 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073606 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323607 break;
3608 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073609 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323610 break;
3611 default:
[email protected]a93bb842010-02-16 23:03:473612 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323613 break;
3614 }
[email protected]051b1372010-04-12 02:42:083615 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323616}
3617
[email protected]297ca1c2011-06-20 23:08:463618bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha() {
3619 return (GLES2Util::GetChannelsForFormat(
3620 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3621}
3622
3623bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353624 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453625 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203626 if (framebuffer) {
3627 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463628 }
3629 if (offscreen_target_frame_buffer_.get()) {
3630 return offscreen_target_depth_format_ != 0;
3631 }
3632 return back_buffer_has_depth_;
3633}
3634
3635bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353636 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453637 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203638 if (framebuffer) {
3639 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463640 }
3641 if (offscreen_target_frame_buffer_.get()) {
3642 return offscreen_target_stencil_format_ != 0 ||
3643 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3644 }
3645 return back_buffer_has_stencil_;
3646}
3647
3648void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]88a61bf2012-10-27 13:00:423649 if (clear_state_dirty_) {
[email protected]297ca1c2011-06-20 23:08:463650 glColorMask(
[email protected]e259eb412012-10-13 05:47:243651 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
3652 state_.color_mask_alpha &&
3653 BoundFramebufferHasColorAttachmentWithAlpha());
[email protected]297ca1c2011-06-20 23:08:463654 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]e259eb412012-10-13 05:47:243655 glDepthMask(state_.depth_mask && have_depth);
[email protected]f731b9462012-10-30 00:35:223656 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
[email protected]297ca1c2011-06-20 23:08:463657 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]e259eb412012-10-13 05:47:243658 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423659 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]e259eb412012-10-13 05:47:243660 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423661 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]f731b9462012-10-30 00:35:223662 EnableDisable(
3663 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3664 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
3665 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
3666 EnableDisable(GL_BLEND, state_.enable_flags.blend);
[email protected]88a61bf2012-10-27 13:00:423667 clear_state_dirty_ = false;
[email protected]297ca1c2011-06-20 23:08:463668 }
3669}
3670
[email protected]1868a342012-11-07 15:56:023671GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]b177ae22011-11-01 03:29:113672 return (offscreen_target_frame_buffer_.get()) ?
3673 offscreen_target_frame_buffer_->id() :
[email protected]1868a342012-11-07 15:56:023674 (surface_ ? surface_->GetBackingFrameBufferObject() : 0);
3675}
3676
3677void GLES2DecoderImpl::RestoreState() const {
[email protected]29a4d902013-02-26 20:18:063678 // Restore the Framebuffer first because of bugs in Intel drivers.
3679 // Intel drivers incorrectly clip the viewport settings to
3680 // the size of the current framebuffer object.
3681 RestoreFramebufferBindings();
3682 state_.RestoreState();
3683}
3684
3685void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]1868a342012-11-07 15:56:023686 GLuint service_id = state_.bound_draw_framebuffer ?
3687 state_.bound_draw_framebuffer->service_id() :
3688 GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063689 if (!features().chromium_framebuffer_multisample) {
3690 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
3691 } else {
3692 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
3693 service_id = state_.bound_read_framebuffer ?
3694 state_.bound_read_framebuffer->service_id() :
3695 GetBackbufferServiceId();
3696 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
3697 }
[email protected]70d34263c2013-01-09 00:27:453698 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:063699}
3700
3701void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
3702 GLuint client_id = 0;
3703 if (texture_manager()->GetClientId(service_id, &client_id)) {
[email protected]370eaf12013-05-18 09:19:493704 Texture* texture = GetTexture(client_id)->texture();
[email protected]9bc9a2e82013-04-03 03:56:253705 GLenum target = texture->target();
3706 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:063707 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253708 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:063709 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253710 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:063711 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253712 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:063713 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253714 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:063715 RestoreTextureUnitBindings(state_.active_texture_unit);
3716 }
[email protected]70d34263c2013-01-09 00:27:453717}
3718
3719void GLES2DecoderImpl::OnFboChanged() const {
3720 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:513721 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
3722}
3723
3724// Called after the FBO is checked for completeness.
3725void GLES2DecoderImpl::OnUseFramebuffer() const {
3726 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
3727 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:323728 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:513729 glScissor(state_.scissor_x,
3730 state_.scissor_y,
3731 state_.scissor_width,
3732 state_.scissor_height);
3733
3734 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
3735 // it's unclear how this bug works.
3736 glFlush();
3737 }
[email protected]b177ae22011-11-01 03:29:113738}
3739
[email protected]051b1372010-04-12 02:42:083740void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:063741 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:083742 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033743 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:063744 framebuffer = GetFramebuffer(client_id);
3745 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:353746 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153747 LOG(ERROR)
3748 << "glBindFramebuffer: id not generated by glGenFramebuffers";
3749 current_decoder_error_ = error::kGenericError;
3750 return;
[email protected]bf5a8d132011-08-16 08:39:353751 }
3752
[email protected]4d8f0dd2013-03-09 14:37:063753 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:033754 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353755 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:063756 framebuffer = GetFramebuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573757 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103758 group_->GetIdAllocator(id_namespaces::kFramebuffers);
3759 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033760 } else {
[email protected]4d8f0dd2013-03-09 14:37:063761 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:083762 }
[email protected]4d8f0dd2013-03-09 14:37:063763 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083764 }
[email protected]4d8f0dd2013-03-09 14:37:063765 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:303766
3767 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:063768 state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303769 }
3770 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:063771 state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303772 }
[email protected]6217d392010-03-25 22:08:353773
[email protected]88a61bf2012-10-27 13:00:423774 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:463775
[email protected]b177ae22011-11-01 03:29:113776 // If we are rendering to the backbuffer get the FBO id for any simulated
3777 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:063778 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:113779 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:463780 }
[email protected]6217d392010-03-25 22:08:353781
[email protected]051b1372010-04-12 02:42:083782 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:453783 OnFboChanged();
[email protected]86093972010-03-11 00:13:563784}
3785
[email protected]051b1372010-04-12 02:42:083786void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:273787 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:083788 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033789 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:273790 renderbuffer = GetRenderbuffer(client_id);
3791 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:353792 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153793 LOG(ERROR)
3794 << "glBindRenderbuffer: id not generated by glGenRenderbuffers";
3795 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353796 return;
3797 }
3798
[email protected]ee2a79c32013-03-10 03:50:273799 // It's a new id so make a renderbuffer renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:033800 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353801 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:273802 renderbuffer = GetRenderbuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573803 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103804 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
3805 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033806 } else {
[email protected]ee2a79c32013-03-10 03:50:273807 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:083808 }
[email protected]ee2a79c32013-03-10 03:50:273809 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083810 }
[email protected]ee2a79c32013-03-10 03:50:273811 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenerbuffer");
3812 state_.bound_renderbuffer = renderbuffer;
[email protected]051b1372010-04-12 02:42:083813 glBindRenderbufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563814}
3815
[email protected]051b1372010-04-12 02:42:083816void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:493817 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:083818 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033819 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:493820 texture_ref = GetTexture(client_id);
3821 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:353822 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153823 LOG(ERROR) << "glBindTexture: id not generated by glGenTextures";
3824 current_decoder_error_ = error::kGenericError;
3825 return;
[email protected]bf5a8d132011-08-16 08:39:353826 }
3827
[email protected]02965c22013-03-09 02:40:073828 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:033829 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:413830 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:353831 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:493832 texture_ref = GetTexture(client_id);
[email protected]3b1ecc262011-08-03 22:49:573833 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103834 group_->GetIdAllocator(id_namespaces::kTextures);
3835 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033836 }
3837 } else {
[email protected]370eaf12013-05-18 09:19:493838 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:083839 }
[email protected]370eaf12013-05-18 09:19:493840 Texture* texture = texture_ref->texture();
[email protected]ae51d192010-04-27 00:48:033841
[email protected]1958e0e2010-04-22 05:17:153842 // Check the texture exists
3843 // Check that we are not trying to bind it to a different target.
[email protected]02965c22013-03-09 02:40:073844 if (texture->target() != 0 && texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:513845 LOCAL_SET_GL_ERROR(
3846 GL_INVALID_OPERATION,
3847 "glBindTexture", "texture bound to more than 1 target.");
[email protected]1958e0e2010-04-22 05:17:153848 return;
3849 }
[email protected]02965c22013-03-09 02:40:073850 if (texture->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:513851 LOCAL_SET_GL_ERROR(
3852 GL_INVALID_OPERATION,
3853 "glBindTexture", "illegal target for stream texture.");
[email protected]b0af4f52011-09-28 22:04:423854 return;
3855 }
[email protected]02965c22013-03-09 02:40:073856 LogClientServiceForInfo(texture, client_id, "glBindTexture");
3857 if (texture->target() == 0) {
[email protected]370eaf12013-05-18 09:19:493858 texture_manager()->SetTarget(texture_ref, target);
[email protected]a93bb842010-02-16 23:03:473859 }
[email protected]02965c22013-03-09 02:40:073860 glBindTexture(target, texture->service_id());
[email protected]32145a92012-12-17 09:01:593861
[email protected]e259eb412012-10-13 05:47:243862 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:503863 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:473864 switch (target) {
3865 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:493866 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:473867 break;
3868 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:493869 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:473870 break;
[email protected]61eeb33f2011-07-26 15:30:313871 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:493872 unit.bound_texture_external_oes = texture_ref;
[email protected]02965c22013-03-09 02:40:073873 if (texture->IsStreamTexture()) {
[email protected]b0af4f52011-09-28 22:04:423874 DCHECK(stream_texture_manager_);
3875 StreamTexture* stream_tex =
[email protected]02965c22013-03-09 02:40:073876 stream_texture_manager_->LookupStreamTexture(texture->service_id());
[email protected]b0af4f52011-09-28 22:04:423877 if (stream_tex)
3878 stream_tex->Update();
3879 }
[email protected]61eeb33f2011-07-26 15:30:313880 break;
[email protected]e51bdf32011-11-23 22:21:463881 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:493882 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:463883 break;
[email protected]a93bb842010-02-16 23:03:473884 default:
3885 NOTREACHED(); // Validation should prevent us getting here.
3886 break;
3887 }
3888}
3889
[email protected]07f54fcc2009-12-22 02:46:303890void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243891 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:123892 if (index != 0 ||
3893 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:243894 glDisableVertexAttribArray(index);
3895 }
[email protected]07f54fcc2009-12-22 02:46:303896 } else {
[email protected]ab09b612013-03-11 22:11:513897 LOCAL_SET_GL_ERROR(
3898 GL_INVALID_VALUE,
3899 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303900 }
3901}
3902
[email protected]60f22d32012-12-12 00:31:583903void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
3904 GLsizei numAttachments,
3905 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:353906 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:583907 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
3908
3909 // Validates the attachments. If one of them fails
3910 // the whole command fails.
3911 for (GLsizei i = 0; i < numAttachments; ++i) {
3912 if ((framebuffer &&
3913 !validators_->attachment.IsValid(attachments[i])) ||
3914 (!framebuffer &&
3915 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:513916 LOCAL_SET_GL_ERROR_INVALID_ENUM(
3917 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:583918 return;
3919 }
3920 }
3921
3922 // Marks each one of them as not cleared
3923 for (GLsizei i = 0; i < numAttachments; ++i) {
3924 if (framebuffer) {
3925 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
3926 texture_manager(),
3927 attachments[i],
3928 false);
3929 } else {
3930 switch (attachments[i]) {
3931 case GL_COLOR_EXT:
3932 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
3933 break;
3934 case GL_DEPTH_EXT:
3935 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
3936 case GL_STENCIL_EXT:
3937 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
3938 break;
3939 default:
3940 NOTREACHED();
3941 break;
3942 }
3943 }
3944 }
3945
3946 glDiscardFramebufferEXT(target, numAttachments, attachments);
3947}
3948
[email protected]07f54fcc2009-12-22 02:46:303949void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243950 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:303951 glEnableVertexAttribArray(index);
3952 } else {
[email protected]ab09b612013-03-11 22:11:513953 LOCAL_SET_GL_ERROR(
3954 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303955 }
3956}
3957
[email protected]a93bb842010-02-16 23:03:473958void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]370eaf12013-05-18 09:19:493959 TextureRef* texture_ref = GetTextureInfoForTarget(target);
3960 if (!texture_ref ||
3961 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:513962 LOCAL_SET_GL_ERROR(
3963 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:473964 return;
3965 }
[email protected]38c0a972012-05-12 00:48:023966
[email protected]12d95352012-12-14 07:23:543967 if (target == GL_TEXTURE_CUBE_MAP) {
3968 for (int i = 0; i < 6; ++i) {
3969 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:493970 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:513971 LOCAL_SET_GL_ERROR(
3972 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:543973 return;
3974 }
3975 }
3976 } else {
[email protected]370eaf12013-05-18 09:19:493977 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:513978 LOCAL_SET_GL_ERROR(
3979 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:543980 return;
3981 }
[email protected]7687479c2012-05-14 23:54:043982 }
3983
[email protected]ab09b612013-03-11 22:11:513984 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:193985 // Workaround for Mac driver bug. In the large scheme of things setting
3986 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:563987 // hit so there's probably no need to make this conditional. The bug appears
3988 // to be that if the filtering mode is set to something that doesn't require
3989 // mipmaps for rendering, or is never set to something other than the default,
3990 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:153991 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:193992 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3993 }
[email protected]a93bb842010-02-16 23:03:473994 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:153995 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:493996 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
3997 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:193998 }
[email protected]ab09b612013-03-11 22:11:513999 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024000 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494001 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024002 }
[email protected]a93bb842010-02-16 23:03:474003}
4004
[email protected]b273e432010-04-12 17:23:584005bool GLES2DecoderImpl::GetHelper(
4006 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584007 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154008 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4009 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434010 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4011 *num_written = 1;
4012 if (params) {
4013 *params = GL_RGBA; // We don't support other formats.
4014 }
4015 return true;
4016 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4017 *num_written = 1;
4018 if (params) {
4019 *params = GL_UNSIGNED_BYTE; // We don't support other types.
4020 }
4021 return true;
4022 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4023 *num_written = 1;
4024 if (params) {
4025 *params = group_->max_fragment_uniform_vectors();
4026 }
4027 return true;
4028 case GL_MAX_VARYING_VECTORS:
4029 *num_written = 1;
4030 if (params) {
4031 *params = group_->max_varying_vectors();
4032 }
4033 return true;
4034 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4035 *num_written = 1;
4036 if (params) {
4037 *params = group_->max_vertex_uniform_vectors();
4038 }
4039 return true;
[email protected]4e8a5b122010-05-08 22:00:104040 }
[email protected]5cb735d2011-10-13 01:37:234041 }
4042 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244043 case GL_MAX_VIEWPORT_DIMS:
4044 if (offscreen_target_frame_buffer_.get()) {
4045 *num_written = 2;
4046 if (params) {
4047 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4048 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4049 }
4050 return true;
4051 }
[email protected]5cb735d2011-10-13 01:37:234052 return false;
[email protected]84afefa2011-10-19 21:45:534053 case GL_MAX_SAMPLES:
4054 *num_written = 1;
4055 if (params) {
4056 params[0] = renderbuffer_manager()->max_samples();
4057 }
4058 return true;
4059 case GL_MAX_RENDERBUFFER_SIZE:
4060 *num_written = 1;
4061 if (params) {
4062 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4063 }
4064 return true;
[email protected]5cb735d2011-10-13 01:37:234065 case GL_MAX_TEXTURE_SIZE:
4066 *num_written = 1;
4067 if (params) {
4068 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4069 }
4070 return true;
4071 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4072 *num_written = 1;
4073 if (params) {
4074 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4075 }
4076 return true;
[email protected]2f143d482013-03-14 18:04:494077 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4078 *num_written = 1;
4079 if (params) {
4080 params[0] = group_->max_color_attachments();
4081 }
4082 return true;
4083 case GL_MAX_DRAW_BUFFERS_ARB:
4084 *num_written = 1;
4085 if (params) {
4086 params[0] = group_->max_draw_buffers();
4087 }
4088 return true;
[email protected]297ca1c2011-06-20 23:08:464089 case GL_ALPHA_BITS:
4090 *num_written = 1;
4091 if (params) {
4092 GLint v = 0;
4093 glGetIntegerv(GL_ALPHA_BITS, &v);
4094 params[0] = BoundFramebufferHasColorAttachmentWithAlpha() ? v : 0;
4095 }
4096 return true;
4097 case GL_DEPTH_BITS:
4098 *num_written = 1;
4099 if (params) {
4100 GLint v = 0;
4101 glGetIntegerv(GL_DEPTH_BITS, &v);
4102 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4103 }
4104 return true;
4105 case GL_STENCIL_BITS:
4106 *num_written = 1;
4107 if (params) {
4108 GLint v = 0;
4109 glGetIntegerv(GL_STENCIL_BITS, &v);
4110 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4111 }
4112 return true;
[email protected]656dcaad2010-05-07 17:18:374113 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114114 *num_written = validators_->compressed_texture_format.GetValues().size();
4115 if (params) {
4116 for (GLint ii = 0; ii < *num_written; ++ii) {
4117 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4118 }
4119 }
[email protected]656dcaad2010-05-07 17:18:374120 return true;
[email protected]b273e432010-04-12 17:23:584121 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4122 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104123 if (params) {
[email protected]302ce6d2011-07-07 23:28:114124 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104125 }
[email protected]b273e432010-04-12 17:23:584126 return true;
4127 case GL_NUM_SHADER_BINARY_FORMATS:
4128 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104129 if (params) {
[email protected]302ce6d2011-07-07 23:28:114130 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104131 }
[email protected]b273e432010-04-12 17:23:584132 return true;
4133 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114134 *num_written = validators_->shader_binary_format.GetValues().size();
4135 if (params) {
4136 for (GLint ii = 0; ii < *num_written; ++ii) {
4137 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4138 }
4139 }
4140 return true;
[email protected]b273e432010-04-12 17:23:584141 case GL_SHADER_COMPILER:
4142 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104143 if (params) {
4144 *params = GL_TRUE;
4145 }
[email protected]b273e432010-04-12 17:23:584146 return true;
[email protected]6b8cf1a2010-05-06 16:13:584147 case GL_ARRAY_BUFFER_BINDING:
4148 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104149 if (params) {
[email protected]e259eb412012-10-13 05:47:244150 if (state_.bound_array_buffer) {
[email protected]4e8a5b122010-05-08 22:00:104151 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244152 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104153 &client_id);
4154 *params = client_id;
4155 } else {
4156 *params = 0;
4157 }
[email protected]6b8cf1a2010-05-06 16:13:584158 }
4159 return true;
4160 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4161 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104162 if (params) {
[email protected]e259eb412012-10-13 05:47:244163 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104164 GLuint client_id = 0;
4165 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254166 state_.vertex_attrib_manager->element_array_buffer()->
4167 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104168 *params = client_id;
4169 } else {
4170 *params = 0;
4171 }
[email protected]6b8cf1a2010-05-06 16:13:584172 }
4173 return true;
4174 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304175 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584176 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104177 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354178 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454179 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204180 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104181 GLuint client_id = 0;
4182 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204183 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304184 *params = client_id;
4185 } else {
4186 *params = 0;
4187 }
4188 }
4189 return true;
[email protected]ebfb73c2012-08-15 02:37:454190 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304191 *num_written = 1;
4192 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354193 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454194 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204195 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304196 GLuint client_id = 0;
4197 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204198 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104199 *params = client_id;
4200 } else {
4201 *params = 0;
4202 }
[email protected]6b8cf1a2010-05-06 16:13:584203 }
4204 return true;
4205 case GL_RENDERBUFFER_BINDING:
4206 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104207 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354208 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204209 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4210 if (renderbuffer) {
[email protected]4e8a5b122010-05-08 22:00:104211 GLuint client_id = 0;
4212 renderbuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204213 renderbuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104214 *params = client_id;
4215 } else {
4216 *params = 0;
4217 }
[email protected]6b8cf1a2010-05-06 16:13:584218 }
4219 return true;
4220 case GL_CURRENT_PROGRAM:
4221 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104222 if (params) {
[email protected]e259eb412012-10-13 05:47:244223 if (state_.current_program) {
[email protected]4e8a5b122010-05-08 22:00:104224 GLuint client_id = 0;
4225 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244226 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104227 *params = client_id;
4228 } else {
4229 *params = 0;
4230 }
[email protected]6b8cf1a2010-05-06 16:13:584231 }
4232 return true;
[email protected]bf835842012-11-19 15:21:514233 case GL_VERTEX_ARRAY_BINDING_OES:
4234 *num_written = 1;
4235 if (params) {
4236 if (state_.vertex_attrib_manager != default_vertex_attrib_manager_) {
4237 GLuint client_id = 0;
4238 vertex_array_manager_->GetClientId(
4239 state_.vertex_attrib_manager->service_id(), &client_id);
4240 *params = client_id;
4241 } else {
4242 *params = 0;
4243 }
4244 }
4245 return true;
[email protected]4e8a5b122010-05-08 22:00:104246 case GL_TEXTURE_BINDING_2D:
4247 *num_written = 1;
4248 if (params) {
[email protected]e259eb412012-10-13 05:47:244249 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]6b8cf1a2010-05-06 16:13:584250 if (unit.bound_texture_2d) {
4251 GLuint client_id = 0;
4252 texture_manager()->GetClientId(
4253 unit.bound_texture_2d->service_id(), &client_id);
4254 *params = client_id;
4255 } else {
4256 *params = 0;
4257 }
[email protected]6b8cf1a2010-05-06 16:13:584258 }
[email protected]4e8a5b122010-05-08 22:00:104259 return true;
4260 case GL_TEXTURE_BINDING_CUBE_MAP:
4261 *num_written = 1;
4262 if (params) {
[email protected]e259eb412012-10-13 05:47:244263 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]6b8cf1a2010-05-06 16:13:584264 if (unit.bound_texture_cube_map) {
4265 GLuint client_id = 0;
4266 texture_manager()->GetClientId(
4267 unit.bound_texture_cube_map->service_id(), &client_id);
4268 *params = client_id;
4269 } else {
4270 *params = 0;
4271 }
[email protected]6b8cf1a2010-05-06 16:13:584272 }
[email protected]4e8a5b122010-05-08 22:00:104273 return true;
[email protected]61eeb33f2011-07-26 15:30:314274 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4275 *num_written = 1;
4276 if (params) {
[email protected]e259eb412012-10-13 05:47:244277 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]61eeb33f2011-07-26 15:30:314278 if (unit.bound_texture_external_oes) {
4279 GLuint client_id = 0;
4280 texture_manager()->GetClientId(
4281 unit.bound_texture_external_oes->service_id(), &client_id);
4282 *params = client_id;
4283 } else {
4284 *params = 0;
4285 }
4286 }
4287 return true;
[email protected]e51bdf32011-11-23 22:21:464288 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4289 *num_written = 1;
4290 if (params) {
[email protected]e259eb412012-10-13 05:47:244291 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]e51bdf32011-11-23 22:21:464292 if (unit.bound_texture_rectangle_arb) {
4293 GLuint client_id = 0;
4294 texture_manager()->GetClientId(
4295 unit.bound_texture_rectangle_arb->service_id(), &client_id);
4296 *params = client_id;
4297 } else {
4298 *params = 0;
4299 }
4300 }
4301 return true;
[email protected]6c75c712012-06-19 15:43:174302 case GL_UNPACK_FLIP_Y_CHROMIUM:
4303 *num_written = 1;
4304 if (params) {
4305 params[0] = unpack_flip_y_;
4306 }
4307 return true;
4308 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4309 *num_written = 1;
4310 if (params) {
4311 params[0] = unpack_premultiply_alpha_;
4312 }
4313 return true;
4314 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4315 *num_written = 1;
4316 if (params) {
4317 params[0] = unpack_unpremultiply_alpha_;
4318 }
4319 return true;
[email protected]b273e432010-04-12 17:23:584320 default:
[email protected]2f143d482013-03-14 18:04:494321 if (pname >= GL_DRAW_BUFFER0_ARB &&
4322 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4323 *num_written = 1;
4324 if (params) {
4325 Framebuffer* framebuffer =
4326 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4327 if (framebuffer) {
4328 params[0] = framebuffer->GetDrawBuffer(pname);
4329 } else { // backbuffer
4330 if (pname == GL_DRAW_BUFFER0_ARB)
4331 params[0] = group_->draw_buffer();
4332 else
4333 params[0] = GL_NONE;
4334 }
4335 }
4336 return true;
4337 }
[email protected]4e8a5b122010-05-08 22:00:104338 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534339 return false;
[email protected]b273e432010-04-12 17:23:584340 }
4341}
4342
[email protected]4e8a5b122010-05-08 22:00:104343bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4344 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264345 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534346 return true;
4347 }
[email protected]4e8a5b122010-05-08 22:00:104348 return GetHelper(pname, NULL, num_values);
4349}
4350
[email protected]b273e432010-04-12 17:23:584351void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4352 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104353 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534354 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554355 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264356 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534357 GetHelper(pname, values.get(), &num_written);
4358 }
[email protected]b273e432010-04-12 17:23:584359 for (GLsizei ii = 0; ii < num_written; ++ii) {
4360 params[ii] = static_cast<GLboolean>(values[ii]);
4361 }
4362 } else {
4363 glGetBooleanv(pname, params);
4364 }
4365}
4366
4367void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4368 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104369 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264370 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534371 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554372 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534373 GetHelper(pname, values.get(), &num_written);
4374 for (GLsizei ii = 0; ii < num_written; ++ii) {
4375 params[ii] = static_cast<GLfloat>(values[ii]);
4376 }
4377 } else {
4378 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584379 }
[email protected]b273e432010-04-12 17:23:584380 }
4381}
4382
4383void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4384 DCHECK(params);
4385 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264386 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534387 !GetHelper(pname, params, &num_written)) {
[email protected]b273e432010-04-12 17:23:584388 glGetIntegerv(pname, params);
4389 }
4390}
4391
[email protected]a0c3e972010-04-21 00:49:134392void GLES2DecoderImpl::DoGetProgramiv(
4393 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424394 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4395 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134396 return;
4397 }
[email protected]df37b9932013-03-08 05:21:424398 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134399}
4400
[email protected]17cfbe0e2013-03-07 01:26:084401void GLES2DecoderImpl::DoGetBufferParameteriv(
4402 GLenum target, GLenum pname, GLint* params) {
4403 Buffer* buffer = GetBufferInfoForTarget(target);
4404 if (!buffer) {
[email protected]ab09b612013-03-11 22:11:514405 LOCAL_SET_GL_ERROR(
[email protected]17cfbe0e2013-03-07 01:26:084406 GL_INVALID_OPERATION, "glGetBufferParameteriv",
4407 "no buffer bound for target");
4408 return;
4409 }
4410 switch (pname) {
4411 case GL_BUFFER_SIZE:
4412 *params = buffer->size();
4413 break;
4414 case GL_BUFFER_USAGE:
4415 *params = buffer->usage();
4416 break;
4417 default:
4418 NOTREACHED();
4419 }
4420}
4421
[email protected]258a3313f2011-10-18 20:13:574422void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424423 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574424 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514425 LOCAL_SET_GL_ERROR(
4426 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574427 return;
4428 }
[email protected]68dcb1f2012-04-07 00:14:564429 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514430 LOCAL_SET_GL_ERROR(
4431 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564432 return;
4433 }
4434 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514435 LOCAL_SET_GL_ERROR(
4436 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564437 return;
4438 }
[email protected]df37b9932013-03-08 05:21:424439 Program* program = GetProgramInfoNotShader(
4440 program_id, "glBindAttribLocation");
4441 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574442 return;
[email protected]558847a2010-03-24 07:02:544443 }
[email protected]df37b9932013-03-08 05:21:424444 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
4445 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574446}
4447
4448error::Error GLES2DecoderImpl::HandleBindAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:354449 uint32 immediate_data_size, const cmds::BindAttribLocation& c) {
[email protected]258a3313f2011-10-18 20:13:574450 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544451 GLuint index = static_cast<GLuint>(c.index);
4452 uint32 name_size = c.data_size;
4453 const char* name = GetSharedMemoryAs<const char*>(
4454 c.name_shm_id, c.name_shm_offset, name_size);
4455 if (name == NULL) {
4456 return error::kOutOfBounds;
4457 }
4458 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574459 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544460 return error::kNoError;
4461}
4462
4463error::Error GLES2DecoderImpl::HandleBindAttribLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:354464 uint32 immediate_data_size, const cmds::BindAttribLocationImmediate& c) {
[email protected]6b8cf1a2010-05-06 16:13:584465 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544466 GLuint index = static_cast<GLuint>(c.index);
4467 uint32 name_size = c.data_size;
4468 const char* name = GetImmediateDataAs<const char*>(
4469 c, name_size, immediate_data_size);
4470 if (name == NULL) {
4471 return error::kOutOfBounds;
4472 }
4473 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574474 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544475 return error::kNoError;
4476}
4477
4478error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:354479 uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) {
[email protected]6b8cf1a2010-05-06 16:13:584480 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544481 GLuint index = static_cast<GLuint>(c.index);
4482 Bucket* bucket = GetBucket(c.name_bucket_id);
4483 if (!bucket || bucket->size() == 0) {
4484 return error::kInvalidArguments;
4485 }
4486 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184487 if (!bucket->GetAsString(&name_str)) {
4488 return error::kInvalidArguments;
4489 }
[email protected]258a3313f2011-10-18 20:13:574490 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544491 return error::kNoError;
4492}
4493
[email protected]2be6abf32012-06-26 00:28:334494void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424495 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334496 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514497 LOCAL_SET_GL_ERROR(
4498 GL_INVALID_VALUE,
4499 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334500 return;
4501 }
4502 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514503 LOCAL_SET_GL_ERROR(
4504 GL_INVALID_OPERATION,
4505 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334506 return;
4507 }
4508 if (location < 0 || static_cast<uint32>(location) >=
4509 (group_->max_fragment_uniform_vectors() +
4510 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514511 LOCAL_SET_GL_ERROR(
4512 GL_INVALID_VALUE,
4513 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334514 return;
4515 }
[email protected]df37b9932013-03-08 05:21:424516 Program* program = GetProgramInfoNotShader(
4517 program_id, "glBindUniformLocationCHROMIUM");
4518 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334519 return;
4520 }
[email protected]df37b9932013-03-08 05:21:424521 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514522 LOCAL_SET_GL_ERROR(
4523 GL_INVALID_VALUE,
4524 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334525 }
4526}
4527
4528error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354529 uint32 immediate_data_size, const cmds::BindUniformLocationCHROMIUM& c) {
[email protected]2be6abf32012-06-26 00:28:334530 GLuint program = static_cast<GLuint>(c.program);
4531 GLint location = static_cast<GLint>(c.location);
4532 uint32 name_size = c.data_size;
4533 const char* name = GetSharedMemoryAs<const char*>(
4534 c.name_shm_id, c.name_shm_offset, name_size);
4535 if (name == NULL) {
4536 return error::kOutOfBounds;
4537 }
4538 String name_str(name, name_size);
4539 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4540 return error::kNoError;
4541}
4542
4543error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMImmediate(
4544 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354545 const cmds::BindUniformLocationCHROMIUMImmediate& c) {
[email protected]2be6abf32012-06-26 00:28:334546 GLuint program = static_cast<GLuint>(c.program);
4547 GLint location = static_cast<GLint>(c.location);
4548 uint32 name_size = c.data_size;
4549 const char* name = GetImmediateDataAs<const char*>(
4550 c, name_size, immediate_data_size);
4551 if (name == NULL) {
4552 return error::kOutOfBounds;
4553 }
4554 String name_str(name, name_size);
4555 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4556 return error::kNoError;
4557}
4558
4559error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4560 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354561 const cmds::BindUniformLocationCHROMIUMBucket& c) {
[email protected]2be6abf32012-06-26 00:28:334562 GLuint program = static_cast<GLuint>(c.program);
4563 GLint location = static_cast<GLint>(c.location);
4564 Bucket* bucket = GetBucket(c.name_bucket_id);
4565 if (!bucket || bucket->size() == 0) {
4566 return error::kInvalidArguments;
4567 }
4568 std::string name_str;
4569 if (!bucket->GetAsString(&name_str)) {
4570 return error::kInvalidArguments;
4571 }
4572 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4573 return error::kNoError;
4574}
4575
[email protected]f7a64ee2010-02-01 22:24:144576error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ed9f9cd2013-02-27 21:12:354577 uint32 immediate_data_size, const cmds::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034578 GLuint client_id = c.shader;
4579 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424580 Shader* shader = GetShader(client_id);
4581 if (shader) {
4582 if (!shader->IsDeleted()) {
4583 glDeleteShader(shader->service_id());
4584 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144585 }
[email protected]ae51d192010-04-27 00:48:034586 } else {
[email protected]ab09b612013-03-11 22:11:514587 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034588 }
[email protected]96449d2c2009-11-25 00:01:324589 }
[email protected]f7a64ee2010-02-01 22:24:144590 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324591}
4592
[email protected]f7a64ee2010-02-01 22:24:144593error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ed9f9cd2013-02-27 21:12:354594 uint32 immediate_data_size, const cmds::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034595 GLuint client_id = c.program;
4596 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424597 Program* program = GetProgram(client_id);
4598 if (program) {
4599 if (!program->IsDeleted()) {
4600 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144601 }
[email protected]ae51d192010-04-27 00:48:034602 } else {
[email protected]ab09b612013-03-11 22:11:514603 LOCAL_SET_GL_ERROR(
4604 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034605 }
[email protected]96449d2c2009-11-25 00:01:324606 }
[email protected]f7a64ee2010-02-01 22:24:144607 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324608}
4609
[email protected]269200b12010-11-18 22:53:064610void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104611 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574612 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104613 for (GLsizei ii = 0; ii < n; ++ii) {
4614 id_allocator->FreeID(ids[ii]);
4615 }
4616}
4617
[email protected]269200b12010-11-18 22:53:064618error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354619 uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104620 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4621 GLsizei n = static_cast<GLsizei>(c.n);
4622 uint32 data_size;
4623 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4624 return error::kOutOfBounds;
4625 }
4626 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4627 c.ids_shm_id, c.ids_shm_offset, data_size);
4628 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514629 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104630 return error::kNoError;
4631 }
4632 if (ids == NULL) {
4633 return error::kOutOfBounds;
4634 }
[email protected]269200b12010-11-18 22:53:064635 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104636 return error::kNoError;
4637}
4638
[email protected]269200b12010-11-18 22:53:064639void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104640 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574641 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104642 if (id_offset == 0) {
4643 for (GLsizei ii = 0; ii < n; ++ii) {
4644 ids[ii] = id_allocator->AllocateID();
4645 }
4646 } else {
4647 for (GLsizei ii = 0; ii < n; ++ii) {
4648 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4649 id_offset = ids[ii] + 1;
4650 }
4651 }
4652}
4653
[email protected]269200b12010-11-18 22:53:064654error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354655 uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104656 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4657 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4658 GLsizei n = static_cast<GLsizei>(c.n);
4659 uint32 data_size;
4660 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4661 return error::kOutOfBounds;
4662 }
4663 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4664 c.ids_shm_id, c.ids_shm_offset, data_size);
4665 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514666 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104667 return error::kNoError;
4668 }
4669 if (ids == NULL) {
4670 return error::kOutOfBounds;
4671 }
[email protected]269200b12010-11-18 22:53:064672 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104673 return error::kNoError;
4674}
4675
[email protected]269200b12010-11-18 22:53:064676void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104677 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574678 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104679 for (GLsizei ii = 0; ii < n; ++ii) {
4680 if (!id_allocator->MarkAsUsed(ids[ii])) {
4681 for (GLsizei jj = 0; jj < ii; ++jj) {
4682 id_allocator->FreeID(ids[jj]);
4683 }
[email protected]ab09b612013-03-11 22:11:514684 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:434685 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4686 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104687 return;
4688 }
4689 }
4690}
4691
[email protected]269200b12010-11-18 22:53:064692error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354693 uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104694 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4695 GLsizei n = static_cast<GLsizei>(c.n);
4696 uint32 data_size;
4697 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4698 return error::kOutOfBounds;
4699 }
4700 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4701 c.ids_shm_id, c.ids_shm_offset, data_size);
4702 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514703 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104704 return error::kNoError;
4705 }
4706 if (ids == NULL) {
4707 return error::kOutOfBounds;
4708 }
[email protected]269200b12010-11-18 22:53:064709 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104710 return error::kNoError;
4711}
4712
[email protected]a7266a92012-06-28 02:11:084713error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444714 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204715 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]e259eb412012-10-13 05:47:244716 UNSHIPPED_TRACE_EVENT_INSTANT2(
4717 "test_gpu", "DoClear",
[email protected]c76faea2013-03-26 07:42:424718 TRACE_EVENT_SCOPE_THREAD,
[email protected]e259eb412012-10-13 05:47:244719 "red", state_.color_clear_red,
4720 "green", state_.color_clear_green);
[email protected]297ca1c2011-06-20 23:08:464721 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:274722 glClear(mask);
4723 }
[email protected]a7266a92012-06-28 02:11:084724 return error::kNoError;
4725}
4726
[email protected]36cef8ce2010-03-16 07:34:454727void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4728 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:034729 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:064730 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4731 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514732 LOCAL_SET_GL_ERROR(
4733 GL_INVALID_OPERATION,
4734 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454735 return;
4736 }
[email protected]ae51d192010-04-27 00:48:034737 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:274738 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:034739 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:274740 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
4741 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514742 LOCAL_SET_GL_ERROR(
4743 GL_INVALID_OPERATION,
4744 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:034745 return;
4746 }
[email protected]ee2a79c32013-03-10 03:50:274747 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:034748 }
[email protected]ab09b612013-03-11 22:11:514749 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:034750 glFramebufferRenderbufferEXT(
4751 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:514752 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:264753 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:274754 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:284755 }
[email protected]4d8f0dd2013-03-09 14:37:064756 if (framebuffer == state_.bound_draw_framebuffer) {
[email protected]88a61bf2012-10-27 13:00:424757 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464758 }
[email protected]81fc9d02013-03-14 23:53:324759 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:284760}
4761
[email protected]3a2e7c7b2010-08-06 01:12:284762void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464763 if (SetCapabilityState(cap, false)) {
4764 glDisable(cap);
4765 }
[email protected]3a2e7c7b2010-08-06 01:12:284766}
4767
4768void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464769 if (SetCapabilityState(cap, true)) {
4770 glEnable(cap);
4771 }
[email protected]3a2e7c7b2010-08-06 01:12:284772}
4773
[email protected]88a61bf2012-10-27 13:00:424774void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4775 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4776 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4777 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:284778}
4779
[email protected]88a61bf2012-10-27 13:00:424780void GLES2DecoderImpl::DoHint(GLenum target, GLenum mode) {
4781 switch (target) {
4782 case GL_GENERATE_MIPMAP_HINT:
4783 state_.hint_generate_mipmap = mode;
4784 break;
4785 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4786 state_.hint_fragment_shader_derivative = mode;
4787 break;
4788 default:
4789 NOTREACHED();
4790 }
4791 glHint(target, mode);
4792}
4793
[email protected]b04e24c2013-01-08 18:35:254794void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:424795 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
4796 state_.sample_coverage_invert = (invert != 0);
4797 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:284798}
4799
[email protected]0d6bfdc2011-11-02 01:32:204800// Assumes framebuffer is complete.
4801void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:064802 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304803 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204804 // bind this to the DRAW point, clear then bind back to READ
4805 // TODO(gman): I don't think there is any guarantee that an FBO that
4806 // is complete on the READ attachment will be complete as a DRAW
4807 // attachment.
4808 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:064809 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:304810 }
[email protected]3a2e7c7b2010-08-06 01:12:284811 GLbitfield clear_bits = 0;
[email protected]4d8f0dd2013-03-09 14:37:064812 if (framebuffer->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
[email protected]297ca1c2011-06-20 23:08:464813 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:204814 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:464815 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:064816 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
4817 1.0f);
[email protected]3a2e7c7b2010-08-06 01:12:284818 glColorMask(true, true, true, true);
4819 clear_bits |= GL_COLOR_BUFFER_BIT;
4820 }
4821
[email protected]4d8f0dd2013-03-09 14:37:064822 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
4823 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284824 glClearStencil(0);
4825 glStencilMask(-1);
4826 clear_bits |= GL_STENCIL_BUFFER_BIT;
4827 }
4828
[email protected]4d8f0dd2013-03-09 14:37:064829 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
4830 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284831 glClearDepth(1.0f);
4832 glDepthMask(true);
4833 clear_bits |= GL_DEPTH_BUFFER_BIT;
4834 }
4835
4836 glDisable(GL_SCISSOR_TEST);
4837 glClear(clear_bits);
4838
[email protected]968351b2011-12-20 08:26:514839 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:064840 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:284841
[email protected]c007aa02010-09-02 22:22:404842 RestoreClearState();
4843
4844 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:064845 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
4846 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:484847 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:064848 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
4849 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:484850 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:404851 }
4852}
4853
4854void GLES2DecoderImpl::RestoreClearState() {
[email protected]88a61bf2012-10-27 13:00:424855 clear_state_dirty_ = true;
[email protected]e259eb412012-10-13 05:47:244856 glClearColor(
4857 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
4858 state_.color_clear_alpha);
4859 glClearStencil(state_.stencil_clear);
4860 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:224861 if (state_.enable_flags.scissor_test) {
[email protected]3a2e7c7b2010-08-06 01:12:284862 glEnable(GL_SCISSOR_TEST);
4863 }
[email protected]36cef8ce2010-03-16 07:34:454864}
4865
4866GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:354867 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:304868 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:204869 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:454870 return GL_FRAMEBUFFER_COMPLETE;
4871 }
[email protected]0d6bfdc2011-11-02 01:32:204872 GLenum completeness = framebuffer->IsPossiblyComplete();
4873 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
4874 return completeness;
4875 }
[email protected]73276522012-11-09 05:50:204876 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:454877}
4878
4879void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:034880 GLenum target, GLenum attachment, GLenum textarget,
4881 GLuint client_texture_id, GLint level) {
[email protected]4d8f0dd2013-03-09 14:37:064882 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4883 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514884 LOCAL_SET_GL_ERROR(
4885 GL_INVALID_OPERATION,
4886 "glFramebufferTexture2D", "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:454887 return;
4888 }
[email protected]ae51d192010-04-27 00:48:034889 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:494890 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:034891 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:494892 texture_ref = GetTexture(client_texture_id);
4893 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:514894 LOCAL_SET_GL_ERROR(
4895 GL_INVALID_OPERATION,
[email protected]370eaf12013-05-18 09:19:494896 "glFramebufferTexture2D", "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:034897 return;
4898 }
[email protected]370eaf12013-05-18 09:19:494899 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:034900 }
[email protected]0d6bfdc2011-11-02 01:32:204901
[email protected]80eb6b52012-01-19 00:14:414902 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:514903 LOCAL_SET_GL_ERROR(
4904 GL_INVALID_VALUE,
4905 "glFramebufferTexture2D", "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:204906 return;
4907 }
4908
[email protected]ab09b612013-03-11 22:11:514909 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferTexture2D");
[email protected]ae51d192010-04-27 00:48:034910 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
[email protected]ab09b612013-03-11 22:11:514911 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferTexture2D");
[email protected]9edc6b22010-12-23 02:00:264912 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494913 framebuffer->AttachTexture(attachment, texture_ref, textarget, level);
[email protected]3a2e7c7b2010-08-06 01:12:284914 }
[email protected]4d8f0dd2013-03-09 14:37:064915 if (framebuffer == state_.bound_draw_framebuffer) {
[email protected]88a61bf2012-10-27 13:00:424916 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464917 }
[email protected]81fc9d02013-03-14 23:53:324918 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:454919}
4920
4921void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
4922 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:064923 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4924 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514925 LOCAL_SET_GL_ERROR(
4926 GL_INVALID_OPERATION,
4927 "glFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454928 return;
4929 }
4930 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:574931 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
4932 GLint type = 0;
4933 GLuint client_id = 0;
4934 glGetFramebufferAttachmentParameterivEXT(
4935 target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type);
4936 switch (type) {
4937 case GL_RENDERBUFFER: {
4938 renderbuffer_manager()->GetClientId(*params, &client_id);
4939 break;
4940 }
4941 case GL_TEXTURE: {
4942 texture_manager()->GetClientId(*params, &client_id);
4943 break;
4944 }
4945 default:
4946 break;
4947 }
4948 *params = client_id;
4949 }
[email protected]36cef8ce2010-03-16 07:34:454950}
4951
4952void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
4953 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:354954 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204955 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4956 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514957 LOCAL_SET_GL_ERROR(
4958 GL_INVALID_OPERATION,
4959 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454960 return;
4961 }
[email protected]3a03a8f2011-03-19 00:51:274962 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434963 case GL_RENDERBUFFER_INTERNAL_FORMAT:
4964 *params = renderbuffer->internal_format();
4965 break;
4966 case GL_RENDERBUFFER_WIDTH:
4967 *params = renderbuffer->width();
4968 break;
4969 case GL_RENDERBUFFER_HEIGHT:
4970 *params = renderbuffer->height();
4971 break;
4972 default:
4973 glGetRenderbufferParameterivEXT(target, pname, params);
4974 break;
[email protected]b71f52c2010-06-18 22:20:204975 }
[email protected]36cef8ce2010-03-16 07:34:454976}
4977
[email protected]8e3e0662010-08-23 18:46:304978void GLES2DecoderImpl::DoBlitFramebufferEXT(
4979 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
4980 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
4981 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:444982 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]62e155e2012-10-23 22:43:154983 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:514984 LOCAL_SET_GL_ERROR(
4985 GL_INVALID_OPERATION,
4986 "glBlitFramebufferEXT", "function not available");
[email protected]8e3e0662010-08-23 18:46:304987 }
[email protected]0c16343f2013-03-08 20:40:164988
4989 if (!CheckBoundFramebuffersValid("glBlitFramebufferEXT")) {
4990 return;
4991 }
4992
[email protected]d058bca2012-11-26 10:27:264993 glDisable(GL_SCISSOR_TEST);
[email protected]5094b0f2010-11-09 19:45:244994 if (IsAngle()) {
4995 glBlitFramebufferANGLE(
4996 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
4997 } else {
4998 glBlitFramebufferEXT(
4999 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5000 }
[email protected]d058bca2012-11-26 10:27:265001 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
[email protected]c76faea2013-03-26 07:42:425002 UNSHIPPED_TRACE_EVENT_INSTANT1("test_gpu", "DoBlit", TRACE_EVENT_SCOPE_THREAD,
5003 "width", srcX1 - srcX0);
[email protected]8e3e0662010-08-23 18:46:305004}
5005
5006void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
5007 GLenum target, GLsizei samples, GLenum internalformat,
5008 GLsizei width, GLsizei height) {
[email protected]62e155e2012-10-23 22:43:155009 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:515010 LOCAL_SET_GL_ERROR(
5011 GL_INVALID_OPERATION,
5012 "glRenderbufferStorageMultisample", "function not available");
[email protected]8e3e0662010-08-23 18:46:305013 return;
5014 }
[email protected]8e3e0662010-08-23 18:46:305015
[email protected]ed9f9cd2013-02-27 21:12:355016 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205017 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5018 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515019 LOCAL_SET_GL_ERROR(
5020 GL_INVALID_OPERATION,
5021 "glRenderbufferStorageMultisample", "no renderbuffer bound");
[email protected]0d6bfdc2011-11-02 01:32:205022 return;
5023 }
5024
[email protected]84afefa2011-10-19 21:45:535025 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515026 LOCAL_SET_GL_ERROR(
5027 GL_INVALID_VALUE,
5028 "glRenderbufferStorageMultisample", "samples too large");
[email protected]84afefa2011-10-19 21:45:535029 return;
5030 }
5031
5032 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5033 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515034 LOCAL_SET_GL_ERROR(
5035 GL_INVALID_VALUE,
5036 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535037 return;
5038 }
5039
[email protected]7989c9e2013-01-23 06:39:265040 uint32 estimated_size = 0;
5041 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
5042 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515043 LOCAL_SET_GL_ERROR(
5044 GL_OUT_OF_MEMORY,
5045 "glRenderbufferStorageMultsample", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265046 return;
[email protected]8e3e0662010-08-23 18:46:305047 }
5048
[email protected]7989c9e2013-01-23 06:39:265049 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515050 LOCAL_SET_GL_ERROR(
5051 GL_OUT_OF_MEMORY,
5052 "glRenderbufferStorageMultsample", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265053 return;
5054 }
5055
5056 GLenum impl_format = RenderbufferManager::
5057 InternalRenderbufferFormatToImplFormat(internalformat);
[email protected]ab09b612013-03-11 22:11:515058 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisample");
[email protected]866b91c52011-03-23 14:38:085059 if (IsAngle()) {
5060 glRenderbufferStorageMultisampleANGLE(
5061 target, samples, impl_format, width, height);
5062 } else {
5063 glRenderbufferStorageMultisampleEXT(
5064 target, samples, impl_format, width, height);
5065 }
[email protected]ab09b612013-03-11 22:11:515066 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisample");
[email protected]9edc6b22010-12-23 02:00:265067 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515068 // TODO(gman): If renderbuffers tracked which framebuffers they were
5069 // attached to we could just mark those framebuffers as not complete.
5070 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205071 renderbuffer_manager()->SetInfo(
5072 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265073 }
[email protected]8e3e0662010-08-23 18:46:305074}
5075
[email protected]36cef8ce2010-03-16 07:34:455076void GLES2DecoderImpl::DoRenderbufferStorage(
5077 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355078 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205079 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5080 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515081 LOCAL_SET_GL_ERROR(
5082 GL_INVALID_OPERATION,
5083 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455084 return;
5085 }
[email protected]876f6fee2010-08-02 23:10:325086
[email protected]84afefa2011-10-19 21:45:535087 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5088 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515089 LOCAL_SET_GL_ERROR(
5090 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535091 return;
5092 }
5093
[email protected]7989c9e2013-01-23 06:39:265094 uint32 estimated_size = 0;
5095 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
5096 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515097 LOCAL_SET_GL_ERROR(
5098 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265099 return;
5100 }
5101
5102 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515103 LOCAL_SET_GL_ERROR(
5104 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265105 return;
[email protected]b71f52c2010-06-18 22:20:205106 }
[email protected]876f6fee2010-08-02 23:10:325107
[email protected]ab09b612013-03-11 22:11:515108 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265109 glRenderbufferStorageEXT(
5110 target, RenderbufferManager::
5111 InternalRenderbufferFormatToImplFormat(internalformat),
5112 width, height);
[email protected]ab09b612013-03-11 22:11:515113 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265114 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515115 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5116 // we could just mark those framebuffers as not complete.
5117 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205118 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265119 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265120 }
[email protected]36cef8ce2010-03-16 07:34:455121}
5122
[email protected]df37b9932013-03-08 05:21:425123void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385124 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425125 Program* program = GetProgramInfoNotShader(
5126 program_id, "glLinkProgram");
5127 if (!program) {
[email protected]a93bb842010-02-16 23:03:475128 return;
5129 }
[email protected]05afda12011-01-20 00:17:345130
[email protected]df37b9932013-03-08 05:21:425131 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395132 ShaderTranslator* vertex_translator = NULL;
5133 ShaderTranslator* fragment_translator = NULL;
5134 if (use_shader_translator_) {
5135 vertex_translator = vertex_translator_;
5136 fragment_translator = fragment_translator_;
5137 }
[email protected]df37b9932013-03-08 05:21:425138 if (program->Link(shader_manager(),
[email protected]65dfc602012-07-23 20:39:395139 vertex_translator,
5140 fragment_translator,
[email protected]e3932abb2013-03-13 00:01:375141 feature_info_,
5142 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425143 if (program == state_.current_program.get()) {
[email protected]62e155e2012-10-23 22:43:155144 if (workarounds().use_current_program_after_successful_link) {
[email protected]df37b9932013-03-08 05:21:425145 glUseProgram(program->service_id());
[email protected]c2a3caf12012-10-23 19:32:005146 }
[email protected]df37b9932013-03-08 05:21:425147 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545148 }
5149 }
[email protected]07f54fcc2009-12-22 02:46:305150};
5151
[email protected]3916c97e2010-02-25 03:20:505152void GLES2DecoderImpl::DoTexParameterf(
5153 GLenum target, GLenum pname, GLfloat param) {
[email protected]370eaf12013-05-18 09:19:495154 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:075155 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515156 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245157 return;
[email protected]07f54fcc2009-12-22 02:46:305158 }
[email protected]cbb22e42011-05-12 23:36:245159
[email protected]02965c22013-03-09 02:40:075160 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505161 "glTexParameterf", GetErrorState(), texture, pname,
5162 static_cast<GLint>(param));
[email protected]07f54fcc2009-12-22 02:46:305163}
5164
[email protected]3916c97e2010-02-25 03:20:505165void GLES2DecoderImpl::DoTexParameteri(
5166 GLenum target, GLenum pname, GLint param) {
[email protected]370eaf12013-05-18 09:19:495167 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:075168 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515169 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245170 return;
[email protected]3916c97e2010-02-25 03:20:505171 }
[email protected]cbb22e42011-05-12 23:36:245172
[email protected]02965c22013-03-09 02:40:075173 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505174 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505175}
5176
5177void GLES2DecoderImpl::DoTexParameterfv(
5178 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]370eaf12013-05-18 09:19:495179 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:075180 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515181 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245182 return;
[email protected]3916c97e2010-02-25 03:20:505183 }
[email protected]cbb22e42011-05-12 23:36:245184
[email protected]02965c22013-03-09 02:40:075185 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505186 "glTexParameterfv", GetErrorState(), texture, pname,
5187 static_cast<GLint>(params[0]));
[email protected]3916c97e2010-02-25 03:20:505188}
5189
5190void GLES2DecoderImpl::DoTexParameteriv(
5191 GLenum target, GLenum pname, const GLint* params) {
[email protected]370eaf12013-05-18 09:19:495192 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:075193 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515194 LOCAL_SET_GL_ERROR(
5195 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245196 return;
[email protected]3916c97e2010-02-25 03:20:505197 }
[email protected]cbb22e42011-05-12 23:36:245198
[email protected]02965c22013-03-09 02:40:075199 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505200 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505201}
5202
[email protected]939e7362010-05-13 20:49:105203bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]e259eb412012-10-13 05:47:245204 if (!state_.current_program) {
[email protected]ad84a3a2012-06-08 21:42:435205 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515206 LOCAL_SET_GL_ERROR(
5207 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435208 return false;
[email protected]939e7362010-05-13 20:49:105209 }
[email protected]e259eb412012-10-13 05:47:245210 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515211 LOCAL_SET_GL_ERROR(
5212 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105213 return false;
5214 }
5215 return true;
5216}
5217
5218bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5219 GLint location, const char* function_name) {
5220 if (!CheckCurrentProgram(function_name)) {
5221 return false;
5222 }
5223 return location != -1;
5224}
5225
[email protected]476ccb72012-12-06 15:52:525226namespace {
5227
5228static const GLenum valid_int_vec1_types_list[] = {
5229 GL_INT,
5230 GL_BOOL,
5231 GL_SAMPLER_2D,
5232 GL_SAMPLER_2D_RECT_ARB,
5233 GL_SAMPLER_CUBE,
5234 GL_SAMPLER_EXTERNAL_OES,
5235};
5236
5237static const GLenum valid_int_vec2_types_list[] = {
5238 GL_INT_VEC2,
5239 GL_BOOL_VEC2,
5240};
5241
5242static const GLenum valid_int_vec3_types_list[] = {
5243 GL_INT_VEC3,
5244 GL_BOOL_VEC3,
5245};
5246
5247static const GLenum valid_int_vec4_types_list[] = {
5248 GL_INT_VEC4,
5249 GL_BOOL_VEC4,
5250};
5251
5252static const GLenum valid_float_vec1_types_list[] = {
5253 GL_FLOAT,
5254 GL_BOOL,
5255};
5256
5257static const GLenum valid_float_vec2_types_list[] = {
5258 GL_FLOAT_VEC2,
5259 GL_BOOL_VEC2,
5260};
5261
5262static const GLenum valid_float_vec3_types_list[] = {
5263 GL_FLOAT_VEC3,
5264 GL_BOOL_VEC3,
5265};
5266
5267static const GLenum valid_float_vec4_types_list[] = {
5268 GL_FLOAT_VEC4,
5269 GL_BOOL_VEC4,
5270};
5271
5272static const GLenum valid_float_mat2_types_list[] = {
5273 GL_FLOAT_MAT2,
5274};
5275
5276static const GLenum valid_float_mat3_types_list[] = {
5277 GL_FLOAT_MAT3,
5278};
5279
5280static const GLenum valid_float_mat4_types_list[] = {
5281 GL_FLOAT_MAT4,
5282};
5283
5284static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec1_base_info = {
5285 valid_int_vec1_types_list,
5286 arraysize(valid_int_vec1_types_list),
5287};
5288
5289static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec2_base_info = {
5290 valid_int_vec2_types_list,
5291 arraysize(valid_int_vec2_types_list),
5292};
5293
5294static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec3_base_info = {
5295 valid_int_vec3_types_list,
5296 arraysize(valid_int_vec3_types_list),
5297};
5298
5299static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec4_base_info = {
5300 valid_int_vec4_types_list,
5301 arraysize(valid_int_vec4_types_list),
5302};
5303
5304static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec1_base_info = {
5305 valid_float_vec1_types_list,
5306 arraysize(valid_float_vec1_types_list),
5307};
5308
5309static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec2_base_info = {
5310 valid_float_vec2_types_list,
5311 arraysize(valid_float_vec2_types_list),
5312};
5313
5314static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec3_base_info = {
5315 valid_float_vec3_types_list,
5316 arraysize(valid_float_vec3_types_list),
5317};
5318
5319static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec4_base_info = {
5320 valid_float_vec4_types_list,
5321 arraysize(valid_float_vec4_types_list),
5322};
5323
5324static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat2_base_info = {
5325 valid_float_mat2_types_list,
5326 arraysize(valid_float_mat2_types_list),
5327};
5328
5329static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat3_base_info = {
5330 valid_float_mat3_types_list,
5331 arraysize(valid_float_mat3_types_list),
5332};
5333
5334static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat4_base_info = {
5335 valid_float_mat4_types_list,
5336 arraysize(valid_float_mat4_types_list),
5337};
5338
5339} // anonymous namespace.
5340
[email protected]43c2f1f2011-03-25 18:35:365341bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:125342 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:525343 const GLES2DecoderImpl::BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:125344 GLint* real_location, GLenum* type, GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365345 DCHECK(type);
5346 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125347 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525348
[email protected]1b0a6752012-02-22 03:44:125349 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105350 return false;
5351 }
[email protected]43c2f1f2011-03-25 18:35:365352 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355353 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245354 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125355 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365356 if (!info) {
[email protected]ab09b612013-03-11 22:11:515357 LOCAL_SET_GL_ERROR(
5358 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105359 return false;
5360 }
[email protected]476ccb72012-12-06 15:52:525361 bool okay = false;
5362 for (size_t ii = 0; ii < base_info.num_valid_types; ++ii) {
5363 if (base_info.valid_types[ii] == info->type) {
5364 okay = true;
5365 break;
5366 }
5367 }
5368 if (!okay) {
[email protected]ab09b612013-03-11 22:11:515369 LOCAL_SET_GL_ERROR(
5370 GL_INVALID_OPERATION, function_name,
5371 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525372 return false;
5373 }
[email protected]43c2f1f2011-03-25 18:35:365374 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515375 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435376 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365377 return false;
5378 }
5379 *count = std::min(info->size - array_index, *count);
5380 if (*count <= 0) {
5381 return false;
5382 }
5383 *type = info->type;
[email protected]939e7362010-05-13 20:49:105384 return true;
5385}
5386
[email protected]1b0a6752012-02-22 03:44:125387void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5388 GLenum type = 0;
5389 GLsizei count = 1;
5390 GLint real_location = -1;
5391 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525392 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5393 &real_location, &type, &count)) {
[email protected]3916c97e2010-02-25 03:20:505394 return;
5395 }
[email protected]e259eb412012-10-13 05:47:245396 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025397 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515398 LOCAL_SET_GL_ERROR(
5399 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465400 return;
5401 }
[email protected]1b0a6752012-02-22 03:44:125402 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505403}
5404
5405void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125406 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365407 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125408 GLint real_location = -1;
5409 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525410 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5411 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365412 return;
5413 }
[email protected]74727112012-06-13 21:18:085414 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5415 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245416 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025417 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515418 LOCAL_SET_GL_ERROR(
5419 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465420 return;
5421 }
[email protected]43c2f1f2011-03-25 18:35:365422 }
[email protected]1b0a6752012-02-22 03:44:125423 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505424}
5425
[email protected]939e7362010-05-13 20:49:105426void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125427 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365428 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125429 GLint real_location = -1;
5430 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525431 fake_location, "glUniform1fv", valid_float_vec1_base_info,
5432 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105433 return;
5434 }
5435 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:555436 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:105437 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535438 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105439 }
[email protected]1b0a6752012-02-22 03:44:125440 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105441 } else {
[email protected]1b0a6752012-02-22 03:44:125442 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105443 }
5444}
5445
5446void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125447 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365448 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125449 GLint real_location = -1;
5450 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525451 fake_location, "glUniform2fv", valid_float_vec2_base_info,
5452 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105453 return;
5454 }
5455 if (type == GL_BOOL_VEC2) {
5456 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:555457 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105458 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535459 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105460 }
[email protected]1b0a6752012-02-22 03:44:125461 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105462 } else {
[email protected]1b0a6752012-02-22 03:44:125463 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105464 }
5465}
5466
5467void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125468 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365469 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125470 GLint real_location = -1;
5471 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525472 fake_location, "glUniform3fv", valid_float_vec3_base_info,
5473 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105474 return;
5475 }
5476 if (type == GL_BOOL_VEC3) {
5477 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:555478 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105479 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535480 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105481 }
[email protected]1b0a6752012-02-22 03:44:125482 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105483 } else {
[email protected]1b0a6752012-02-22 03:44:125484 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105485 }
5486}
5487
5488void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125489 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365490 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125491 GLint real_location = -1;
5492 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525493 fake_location, "glUniform4fv", valid_float_vec4_base_info,
5494 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105495 return;
5496 }
5497 if (type == GL_BOOL_VEC4) {
5498 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:555499 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105500 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535501 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105502 }
[email protected]1b0a6752012-02-22 03:44:125503 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105504 } else {
[email protected]1b0a6752012-02-22 03:44:125505 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105506 }
5507}
5508
[email protected]43c2f1f2011-03-25 18:35:365509void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125510 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365511 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125512 GLint real_location = -1;
5513 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525514 fake_location, "glUniform2iv", valid_int_vec2_base_info,
5515 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365516 return;
5517 }
[email protected]1b0a6752012-02-22 03:44:125518 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365519}
5520
5521void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125522 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365523 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125524 GLint real_location = -1;
5525 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525526 fake_location, "glUniform3iv", valid_int_vec3_base_info,
5527 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365528 return;
5529 }
[email protected]1b0a6752012-02-22 03:44:125530 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365531}
5532
5533void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125534 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365535 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125536 GLint real_location = -1;
5537 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525538 fake_location, "glUniform4iv", valid_int_vec4_base_info,
5539 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365540 return;
5541 }
[email protected]1b0a6752012-02-22 03:44:125542 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365543}
5544
5545void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:125546 GLint fake_location, GLsizei count, GLboolean transpose,
5547 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365548 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125549 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365550 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525551 fake_location, "glUniformMatrix2fv", valid_float_mat2_base_info,
5552 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365553 return;
5554 }
[email protected]1b0a6752012-02-22 03:44:125555 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365556}
5557
5558void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:125559 GLint fake_location, GLsizei count, GLboolean transpose,
5560 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365561 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125562 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365563 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525564 fake_location, "glUniformMatrix3fv", valid_float_mat3_base_info,
5565 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365566 return;
5567 }
[email protected]1b0a6752012-02-22 03:44:125568 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365569}
5570
5571void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:125572 GLint fake_location, GLsizei count, GLboolean transpose,
5573 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365574 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125575 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365576 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525577 fake_location, "glUniformMatrix4fv", valid_float_mat4_base_info,
5578 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365579 return;
5580 }
[email protected]1b0a6752012-02-22 03:44:125581 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365582}
5583
[email protected]df37b9932013-03-08 05:21:425584void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:035585 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:425586 Program* program = NULL;
5587 if (program_id) {
5588 program = GetProgramInfoNotShader(program_id, "glUseProgram");
5589 if (!program) {
[email protected]ae51d192010-04-27 00:48:035590 return;
5591 }
[email protected]df37b9932013-03-08 05:21:425592 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:505593 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:515594 LOCAL_SET_GL_ERROR(
5595 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:505596 return;
5597 }
[email protected]df37b9932013-03-08 05:21:425598 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:505599 }
[email protected]e259eb412012-10-13 05:47:245600 if (state_.current_program) {
5601 program_manager()->UnuseProgram(shader_manager(), state_.current_program);
[email protected]ca488e12010-12-13 20:06:145602 }
[email protected]df37b9932013-03-08 05:21:425603 state_.current_program = program;
5604 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:545605 glUseProgram(service_id);
[email protected]e259eb412012-10-13 05:47:245606 if (state_.current_program) {
5607 program_manager()->UseProgram(state_.current_program);
[email protected]ca488e12010-12-13 20:06:145608 }
[email protected]3916c97e2010-02-25 03:20:505609}
5610
[email protected]ab09b612013-03-11 22:11:515611void GLES2DecoderImpl::RenderWarning(
5612 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:325613 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015614}
5615
[email protected]ab09b612013-03-11 22:11:515616void GLES2DecoderImpl::PerformanceWarning(
5617 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:505618 logger_.LogMessage(filename, line,
5619 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015620}
5621
[email protected]df37b9932013-03-08 05:21:425622void GLES2DecoderImpl::ForceCompileShaderIfPending(Shader* shader) {
5623 if (shader->compilation_status() ==
[email protected]ed9f9cd2013-02-27 21:12:355624 Shader::PENDING_DEFERRED_COMPILE) {
[email protected]c447acd2012-07-23 23:48:415625 ShaderTranslator* translator = NULL;
5626 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:425627 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]c447acd2012-07-23 23:48:415628 vertex_translator_.get() : fragment_translator_.get();
5629 }
5630 // We know there will be no errors, because we only defer compilation on
5631 // shaders that were previously compiled successfully.
[email protected]df37b9932013-03-08 05:21:425632 program_manager()->ForceCompileShader(shader->deferred_compilation_source(),
5633 shader,
[email protected]c447acd2012-07-23 23:48:415634 translator,
5635 feature_info_);
5636 }
5637}
5638
[email protected]ef526492010-06-02 23:12:255639bool GLES2DecoderImpl::SetBlackTextureForNonRenderableTextures() {
[email protected]e259eb412012-10-13 05:47:245640 DCHECK(state_.current_program);
[email protected]ef526492010-06-02 23:12:255641 // Only check if there are some unrenderable textures.
5642 if (!texture_manager()->HaveUnrenderableTextures()) {
5643 return false;
5644 }
[email protected]5190e942013-05-17 03:53:425645 LOCAL_PERFORMANCE_WARNING("Some textures are unrenderable.");
[email protected]ef526492010-06-02 23:12:255646 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:355647 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245648 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505649 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355650 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245651 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505652 DCHECK(uniform_info);
5653 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5654 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025655 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245656 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:495657 TextureRef* texture =
[email protected]61eeb33f2011-07-26 15:30:315658 texture_unit.GetInfoForSamplerType(uniform_info->type);
[email protected]02965c22013-03-09 02:40:075659 if (!texture || !texture_manager()->CanRender(texture)) {
[email protected]ef526492010-06-02 23:12:255660 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:505661 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5662 glBindTexture(
[email protected]61eeb33f2011-07-26 15:30:315663 GetBindTargetForSamplerType(uniform_info->type),
[email protected]00f893d2010-08-24 18:55:495664 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:515665 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:015666 std::string("texture bound to texture unit ") +
5667 base::IntToString(texture_unit_index) +
5668 " is not renderable. It maybe non-power-of-2 and have "
5669 " incompatible texture filtering or is not "
5670 "'texture complete'");
[email protected]3916c97e2010-02-25 03:20:505671 }
5672 }
5673 // else: should this be an error?
5674 }
5675 }
[email protected]ef526492010-06-02 23:12:255676 return textures_set;
[email protected]3916c97e2010-02-25 03:20:505677}
5678
5679void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() {
[email protected]e259eb412012-10-13 05:47:245680 DCHECK(state_.current_program);
[email protected]ed9f9cd2013-02-27 21:12:355681 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245682 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505683 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355684 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245685 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505686 DCHECK(uniform_info);
5687 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5688 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025689 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245690 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:495691 TextureRef* texture_ref = uniform_info->type == GL_SAMPLER_2D ?
[email protected]02965c22013-03-09 02:40:075692 texture_unit.bound_texture_2d :
5693 texture_unit.bound_texture_cube_map;
[email protected]370eaf12013-05-18 09:19:495694 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:505695 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:495696 // Get the texture_ref info that was previously bound here.
5697 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D ?
[email protected]3916c97e2010-02-25 03:20:505698 texture_unit.bound_texture_2d :
5699 texture_unit.bound_texture_cube_map;
5700 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:495701 texture_ref ? texture_ref->service_id() : 0);
[email protected]3916c97e2010-02-25 03:20:505702 }
5703 }
5704 }
5705 }
5706 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:245707 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:305708}
5709
[email protected]0d6bfdc2011-11-02 01:32:205710bool GLES2DecoderImpl::ClearUnclearedTextures() {
5711 // Only check if there are some uncleared textures.
5712 if (!texture_manager()->HaveUnsafeTextures()) {
5713 return true;
5714 }
5715
5716 // 1: Check all textures we are about to render with.
[email protected]e259eb412012-10-13 05:47:245717 if (state_.current_program) {
[email protected]ed9f9cd2013-02-27 21:12:355718 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245719 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:205720 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355721 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245722 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:205723 DCHECK(uniform_info);
5724 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5725 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025726 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245727 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:495728 TextureRef* texture_ref =
[email protected]0d6bfdc2011-11-02 01:32:205729 texture_unit.GetInfoForSamplerType(uniform_info->type);
[email protected]370eaf12013-05-18 09:19:495730 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
5731 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:205732 return false;
5733 }
5734 }
5735 }
5736 }
5737 }
5738 }
5739 return true;
5740}
5741
[email protected]c6aef902012-02-14 03:31:425742bool GLES2DecoderImpl::IsDrawValid(
[email protected]ad84a3a2012-06-08 21:42:435743 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
[email protected]689fa1c52010-06-09 18:35:035744 // NOTE: We specifically do not check current_program->IsValid() because
5745 // it could never be invalid since glUseProgram would have failed. While
5746 // glLinkProgram could later mark the program as invalid the previous
5747 // valid program will still function if it is still the current program.
[email protected]e259eb412012-10-13 05:47:245748 if (!state_.current_program) {
[email protected]3916c97e2010-02-25 03:20:505749 // The program does not exist.
5750 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:515751 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:505752 return false;
5753 }
[email protected]c6aef902012-02-14 03:31:425754
[email protected]17cfbe0e2013-03-07 01:26:085755 return state_.vertex_attrib_manager->ValidateBindings(
5756 function_name,
5757 this,
5758 feature_info_.get(),
5759 state_.current_program,
5760 max_vertex_accessed,
5761 primcount);
[email protected]b1122982010-05-17 23:04:245762}
5763
[email protected]c13e1da62011-09-09 21:48:305764bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:435765 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:305766 DCHECK(simulated);
5767 *simulated = false;
5768
[email protected]876f6fee2010-08-02 23:10:325769 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:305770 return true;
[email protected]876f6fee2010-08-02 23:10:325771
[email protected]ac77603c72013-03-08 13:52:065772 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:355773 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:245774 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:245775 bool attrib_0_used =
5776 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:065777 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:305778 return true;
[email protected]b1122982010-05-17 23:04:245779 }
5780
[email protected]b1122982010-05-17 23:04:245781 // Make a buffer with a single repeated vec4 value enough to
5782 // simulate the constant value that is supposed to be here.
5783 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:305784 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:475785 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:305786
5787 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:475788 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305789 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:515790 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305791 return false;
5792 }
5793
[email protected]ab09b612013-03-11 22:11:515794 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:015795 "Attribute 0 is disabled. This has signficant performance penalty");
5796
[email protected]ab09b612013-03-11 22:11:515797 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:305798 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
5799
[email protected]8f0b86c2f2012-04-10 05:48:285800 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
5801 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:495802 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305803 GLenum error = glGetError();
5804 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:515805 LOCAL_SET_GL_ERROR(
5806 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305807 return false;
5808 }
[email protected]fc753442011-02-04 19:49:495809 }
[email protected]af6380962012-11-29 23:24:135810
5811 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:285812 if (new_buffer ||
5813 (attrib_0_used &&
5814 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:135815 (value.v[0] != attrib_0_value_.v[0] ||
5816 value.v[1] != attrib_0_value_.v[1] ||
5817 value.v[2] != attrib_0_value_.v[2] ||
5818 value.v[3] != attrib_0_value_.v[3])))) {
5819 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:495820 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
5821 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:135822 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:245823 attrib_0_size_ = size_needed;
5824 }
5825
5826 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
5827
[email protected]ac77603c72013-03-08 13:52:065828 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:425829 glVertexAttribDivisorANGLE(0, 0);
5830
[email protected]c13e1da62011-09-09 21:48:305831 *simulated = true;
[email protected]b1122982010-05-17 23:04:245832 return true;
[email protected]b1122982010-05-17 23:04:245833}
5834
[email protected]ac77603c72013-03-08 13:52:065835void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib_index) {
5836 const VertexAttrib* attrib =
5837 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
5838 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
5839 Buffer* buffer = attrib->buffer();
[email protected]b10492f2013-03-08 05:24:075840 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
[email protected]b1122982010-05-17 23:04:245841 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:065842 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
5843 attrib->gl_stride(), ptr);
5844 if (attrib->divisor())
5845 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:245846 glBindBuffer(
5847 GL_ARRAY_BUFFER,
5848 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:285849
[email protected]265f8992012-07-20 01:03:145850 // Never touch vertex attribute 0's state (in particular, never
5851 // disable it) when running on desktop GL because it will never be
5852 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:065853 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:145854 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:065855 if (attrib->enabled()) {
5856 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:145857 } else {
[email protected]ac77603c72013-03-08 13:52:065858 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:145859 }
[email protected]43410e92012-04-20 17:06:285860 }
[email protected]b1122982010-05-17 23:04:245861}
[email protected]07f54fcc2009-12-22 02:46:305862
[email protected]8fbedc02010-11-18 18:43:405863bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:435864 const char* function_name,
[email protected]c6aef902012-02-14 03:31:425865 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:405866 DCHECK(simulated);
5867 *simulated = false;
5868 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
5869 return true;
5870
[email protected]e259eb412012-10-13 05:47:245871 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:405872 return true;
5873 }
5874
[email protected]ab09b612013-03-11 22:11:515875 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:015876 "GL_FIXED attributes have a signficant performance penalty");
5877
[email protected]8fbedc02010-11-18 18:43:405878 // NOTE: we could be smart and try to check if a buffer is used
5879 // twice in 2 different attribs, find the overlapping parts and therefore
5880 // duplicate the minimum amount of data but this whole code path is not meant
5881 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
5882 // tests so we just add to the buffer attrib used.
5883
[email protected]c13e1da62011-09-09 21:48:305884 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:065885 const VertexAttribManager::VertexAttribList& enabled_attribs =
5886 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
5887 for (VertexAttribManager::VertexAttribList::const_iterator it =
5888 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
5889 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:355890 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:065891 state_.current_program->GetAttribInfoByLocation(attrib->index());
5892 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
5893 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:425894 GLuint num_vertices = max_accessed + 1;
5895 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:515896 LOCAL_SET_GL_ERROR(
5897 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425898 return false;
5899 }
[email protected]8fbedc02010-11-18 18:43:405900 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:065901 attrib->CanAccess(max_accessed) &&
5902 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:475903 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:065904 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:475905 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:515906 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435907 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405908 return false;
5909 }
5910 }
5911 }
5912
[email protected]3aad1a32012-09-07 20:54:475913 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
5914 uint32 size_needed = 0;
5915 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305916 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:515917 LOCAL_SET_GL_ERROR(
5918 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405919 return false;
5920 }
5921
[email protected]ab09b612013-03-11 22:11:515922 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:405923
5924 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:305925 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:405926 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305927 GLenum error = glGetError();
5928 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:515929 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435930 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:305931 return false;
5932 }
[email protected]8fbedc02010-11-18 18:43:405933 }
5934
5935 // Copy the elements and convert to float
5936 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:065937 for (VertexAttribManager::VertexAttribList::const_iterator it =
5938 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
5939 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:355940 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:065941 state_.current_program->GetAttribInfoByLocation(attrib->index());
5942 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:425943 max_vertex_accessed);
5944 GLuint num_vertices = max_accessed + 1;
5945 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:515946 LOCAL_SET_GL_ERROR(
5947 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425948 return false;
5949 }
[email protected]8fbedc02010-11-18 18:43:405950 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:065951 attrib->CanAccess(max_accessed) &&
5952 attrib->type() == GL_FIXED) {
5953 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:405954 int size = num_elements * num_vertices;
[email protected]40d90a22013-04-09 03:39:555955 scoped_ptr<float[]> data(new float[size]);
[email protected]8fbedc02010-11-18 18:43:405956 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:065957 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:405958 const int32* end = src + num_elements;
5959 float* dst = data.get();
5960 while (src != end) {
5961 *dst++ = static_cast<float>(*src++) / 65536.0f;
5962 }
5963 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
5964 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:065965 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:405966 reinterpret_cast<GLvoid*>(offset));
5967 offset += size;
5968 }
5969 }
5970 *simulated = true;
5971 return true;
5972}
5973
5974void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
5975 // There's no need to call glVertexAttribPointer because we shadow all the
5976 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:245977 glBindBuffer(
5978 GL_ARRAY_BUFFER,
5979 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0);
[email protected]8fbedc02010-11-18 18:43:405980}
5981
[email protected]ad84a3a2012-06-08 21:42:435982error::Error GLES2DecoderImpl::DoDrawArrays(
5983 const char* function_name,
5984 bool instanced,
5985 GLenum mode,
5986 GLint first,
5987 GLsizei count,
5988 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:085989 if (ShouldDeferDraws())
5990 return error::kDeferCommandUntilLater;
[email protected]38d139d2011-07-14 00:38:435991 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:515992 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:435993 return error::kNoError;
5994 }
5995 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:515996 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:435997 return error::kNoError;
5998 }
[email protected]c6aef902012-02-14 03:31:425999 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516000 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426001 return error::kNoError;
6002 }
[email protected]ad84a3a2012-06-08 21:42:436003 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436004 return error::kNoError;
6005 }
6006 // We have to check this here because the prototype for glDrawArrays
6007 // is GLint not GLsizei.
6008 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516009 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436010 return error::kNoError;
6011 }
6012
[email protected]c6aef902012-02-14 03:31:426013 if (count == 0 || (instanced && primcount == 0)) {
[email protected]ab09b612013-03-11 22:11:516014 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436015 return error::kNoError;
6016 }
6017
6018 GLuint max_vertex_accessed = first + count - 1;
[email protected]ad84a3a2012-06-08 21:42:436019 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206020 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516021 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206022 return error::kNoError;
6023 }
[email protected]c13e1da62011-09-09 21:48:306024 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436025 if (!SimulateAttrib0(
6026 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306027 return error::kNoError;
6028 }
[email protected]38d139d2011-07-14 00:38:436029 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436030 if (SimulateFixedAttribs(
6031 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6032 primcount)) {
[email protected]38d139d2011-07-14 00:38:436033 bool textures_set = SetBlackTextureForNonRenderableTextures();
6034 ApplyDirtyState();
[email protected]c6aef902012-02-14 03:31:426035 if (!instanced) {
6036 glDrawArrays(mode, first, count);
6037 } else {
6038 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6039 }
[email protected]22e3f552012-03-13 01:54:196040 ProcessPendingQueries();
[email protected]38d139d2011-07-14 00:38:436041 if (textures_set) {
6042 RestoreStateForNonRenderableTextures();
6043 }
6044 if (simulated_fixed_attribs) {
6045 RestoreStateForSimulatedFixedAttribs();
6046 }
6047 }
6048 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286049 RestoreStateForAttrib(0);
[email protected]38d139d2011-07-14 00:38:436050 }
[email protected]38d139d2011-07-14 00:38:436051 }
6052 return error::kNoError;
6053}
6054
[email protected]c6aef902012-02-14 03:31:426055error::Error GLES2DecoderImpl::HandleDrawArrays(
[email protected]ed9f9cd2013-02-27 21:12:356056 uint32 immediate_data_size, const cmds::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:436057 return DoDrawArrays("glDrawArrays",
6058 false,
[email protected]c6aef902012-02-14 03:31:426059 static_cast<GLenum>(c.mode),
6060 static_cast<GLint>(c.first),
6061 static_cast<GLsizei>(c.count),
6062 0);
6063}
6064
6065error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356066 uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156067 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516068 LOCAL_SET_GL_ERROR(
6069 GL_INVALID_OPERATION,
6070 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426071 return error::kNoError;
6072 }
[email protected]ad84a3a2012-06-08 21:42:436073 return DoDrawArrays("glDrawArraysIntancedANGLE",
6074 true,
[email protected]c6aef902012-02-14 03:31:426075 static_cast<GLenum>(c.mode),
6076 static_cast<GLint>(c.first),
6077 static_cast<GLsizei>(c.count),
6078 static_cast<GLsizei>(c.primcount));
6079}
6080
[email protected]ad84a3a2012-06-08 21:42:436081error::Error GLES2DecoderImpl::DoDrawElements(
6082 const char* function_name,
6083 bool instanced,
6084 GLenum mode,
6085 GLsizei count,
6086 GLenum type,
6087 int32 offset,
6088 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:086089 if (ShouldDeferDraws())
6090 return error::kDeferCommandUntilLater;
[email protected]e259eb412012-10-13 05:47:246091 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516092 LOCAL_SET_GL_ERROR(
6093 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296094 return error::kNoError;
6095 }
6096
[email protected]8eee29c2010-04-29 03:38:296097 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516098 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296099 return error::kNoError;
6100 }
6101 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516102 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296103 return error::kNoError;
6104 }
[email protected]9438b012010-06-15 22:55:056105 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516106 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296107 return error::kNoError;
6108 }
[email protected]9438b012010-06-15 22:55:056109 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516110 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296111 return error::kNoError;
6112 }
[email protected]c6aef902012-02-14 03:31:426113 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516114 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426115 return error::kNoError;
6116 }
[email protected]8eee29c2010-04-29 03:38:296117
[email protected]ad84a3a2012-06-08 21:42:436118 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276119 return error::kNoError;
6120 }
6121
[email protected]c6aef902012-02-14 03:31:426122 if (count == 0 || (instanced && primcount == 0)) {
[email protected]6c788fb72010-08-26 02:16:316123 return error::kNoError;
6124 }
6125
[email protected]8eee29c2010-04-29 03:38:296126 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086127 Buffer* element_array_buffer =
6128 state_.vertex_attrib_manager->element_array_buffer();
6129
6130 if (!element_array_buffer->GetMaxValueForRange(
6131 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516132 LOCAL_SET_GL_ERROR(
6133 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296134 return error::kNoError;
6135 }
6136
[email protected]ad84a3a2012-06-08 21:42:436137 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206138 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516139 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206140 return error::kNoError;
6141 }
[email protected]c13e1da62011-09-09 21:48:306142 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436143 if (!SimulateAttrib0(
6144 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306145 return error::kNoError;
6146 }
[email protected]8fbedc02010-11-18 18:43:406147 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436148 if (SimulateFixedAttribs(
6149 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6150 primcount)) {
[email protected]8fbedc02010-11-18 18:43:406151 bool textures_set = SetBlackTextureForNonRenderableTextures();
[email protected]297ca1c2011-06-20 23:08:466152 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086153 // TODO(gman): Refactor to hide these details in BufferManager or
6154 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406155 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086156 bool used_client_side_array = false;
6157 if (element_array_buffer->IsClientSideArray()) {
6158 used_client_side_array = true;
6159 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6160 indices = element_array_buffer->GetRange(offset, 0);
6161 }
6162
[email protected]c6aef902012-02-14 03:31:426163 if (!instanced) {
6164 glDrawElements(mode, count, type, indices);
6165 } else {
6166 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6167 }
[email protected]17cfbe0e2013-03-07 01:26:086168
6169 if (used_client_side_array) {
6170 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6171 element_array_buffer->service_id());
6172 }
6173
[email protected]22e3f552012-03-13 01:54:196174 ProcessPendingQueries();
[email protected]8fbedc02010-11-18 18:43:406175 if (textures_set) {
6176 RestoreStateForNonRenderableTextures();
6177 }
6178 if (simulated_fixed_attribs) {
6179 RestoreStateForSimulatedFixedAttribs();
6180 }
[email protected]ba3176a2009-12-16 18:19:466181 }
[email protected]b1122982010-05-17 23:04:246182 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286183 RestoreStateForAttrib(0);
[email protected]b1122982010-05-17 23:04:246184 }
[email protected]96449d2c2009-11-25 00:01:326185 }
[email protected]f7a64ee2010-02-01 22:24:146186 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326187}
6188
[email protected]c6aef902012-02-14 03:31:426189error::Error GLES2DecoderImpl::HandleDrawElements(
[email protected]ed9f9cd2013-02-27 21:12:356190 uint32 immediate_data_size, const cmds::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:436191 return DoDrawElements("glDrawElements",
6192 false,
[email protected]c6aef902012-02-14 03:31:426193 static_cast<GLenum>(c.mode),
6194 static_cast<GLsizei>(c.count),
6195 static_cast<GLenum>(c.type),
6196 static_cast<int32>(c.index_offset),
6197 0);
6198}
6199
6200error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356201 uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156202 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516203 LOCAL_SET_GL_ERROR(
6204 GL_INVALID_OPERATION,
6205 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426206 return error::kNoError;
6207 }
[email protected]ad84a3a2012-06-08 21:42:436208 return DoDrawElements("glDrawElementsInstancedANGLE",
6209 true,
[email protected]c6aef902012-02-14 03:31:426210 static_cast<GLenum>(c.mode),
6211 static_cast<GLsizei>(c.count),
6212 static_cast<GLenum>(c.type),
6213 static_cast<int32>(c.index_offset),
6214 static_cast<GLsizei>(c.primcount));
6215}
6216
[email protected]269200b12010-11-18 22:53:066217GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236218 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6219 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076220 Buffer* buffer = GetBuffer(buffer_id);
6221 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036222 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516223 LOCAL_SET_GL_ERROR(
6224 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236225 } else {
[email protected]b10492f2013-03-08 05:24:076226 if (!buffer->GetMaxValueForRange(
6227 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036228 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516229 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066230 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436231 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236232 }
6233 }
6234 return max_vertex_accessed;
6235}
6236
[email protected]96449d2c2009-11-25 00:01:326237// Calls glShaderSource for the various versions of the ShaderSource command.
6238// Assumes that data / data_size points to a piece of memory that is in range
6239// of whatever context it came from (shared memory, immediate memory, bucket
6240// memory.)
[email protected]45bf5152010-02-12 00:11:316241error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036242 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576243 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426244 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6245 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316246 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326247 }
[email protected]45bf5152010-02-12 00:11:316248 // Note: We don't actually call glShaderSource here. We wait until
6249 // the call to glCompileShader.
[email protected]df37b9932013-03-08 05:21:426250 shader->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:146251 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326252}
6253
[email protected]f7a64ee2010-02-01 22:24:146254error::Error GLES2DecoderImpl::HandleShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356255 uint32 immediate_data_size, const cmds::ShaderSource& c) {
[email protected]96449d2c2009-11-25 00:01:326256 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316257 const char* data = GetSharedMemoryAs<const char*>(
[email protected]96449d2c2009-11-25 00:01:326258 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]ba3176a2009-12-16 18:19:466259 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146260 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326261 }
[email protected]ae51d192010-04-27 00:48:036262 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]96449d2c2009-11-25 00:01:326263}
6264
[email protected]f7a64ee2010-02-01 22:24:146265error::Error GLES2DecoderImpl::HandleShaderSourceImmediate(
[email protected]ed9f9cd2013-02-27 21:12:356266 uint32 immediate_data_size, const cmds::ShaderSourceImmediate& c) {
[email protected]96449d2c2009-11-25 00:01:326267 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316268 const char* data = GetImmediateDataAs<const char*>(
[email protected]07f54fcc2009-12-22 02:46:306269 c, data_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:466270 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146271 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326272 }
[email protected]ae51d192010-04-27 00:48:036273 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]45bf5152010-02-12 00:11:316274}
6275
[email protected]558847a2010-03-24 07:02:546276error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
[email protected]ed9f9cd2013-02-27 21:12:356277 uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:546278 Bucket* bucket = GetBucket(c.data_bucket_id);
6279 if (!bucket || bucket->size() == 0) {
6280 return error::kInvalidArguments;
6281 }
6282 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036283 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546284 bucket->size() - 1);
6285}
6286
[email protected]ae51d192010-04-27 00:48:036287void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386288 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426289 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6290 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316291 return;
6292 }
[email protected]f57bb282010-11-12 00:51:346293 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186294 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426295 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456296 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416297 }
[email protected]de17df392010-04-23 21:09:416298
[email protected]df37b9932013-03-08 05:21:426299 program_manager()->DoCompileShader(shader, translator, feature_info_);
[email protected]45bf5152010-02-12 00:11:316300};
6301
[email protected]ddd968b82010-03-02 00:44:296302void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426303 GLuint shader_id, GLenum pname, GLint* params) {
6304 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6305 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296306 return;
6307 }
[email protected]8f1ccdac2010-05-19 21:01:486308 switch (pname) {
6309 case GL_SHADER_SOURCE_LENGTH:
[email protected]df37b9932013-03-08 05:21:426310 *params = shader->source() ? shader->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:486311 return;
6312 case GL_COMPILE_STATUS:
[email protected]df37b9932013-03-08 05:21:426313 *params = compile_shader_always_succeeds_ ? true : shader->IsValid();
[email protected]e5186162010-06-14 18:54:416314 return;
[email protected]8f1ccdac2010-05-19 21:01:486315 case GL_INFO_LOG_LENGTH:
[email protected]df37b9932013-03-08 05:21:426316 *params = shader->log_info() ? shader->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:416317 return;
[email protected]d6a53e42011-10-05 00:09:366318 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]df37b9932013-03-08 05:21:426319 ForceCompileShaderIfPending(shader);
6320 *params = shader->translated_source() ?
6321 shader->translated_source()->size() + 1 : 0;
[email protected]d6a53e42011-10-05 00:09:366322 return;
[email protected]8f1ccdac2010-05-19 21:01:486323 default:
6324 break;
[email protected]ddd968b82010-03-02 00:44:296325 }
[email protected]df37b9932013-03-08 05:21:426326 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296327}
6328
[email protected]ae51d192010-04-27 00:48:036329error::Error GLES2DecoderImpl::HandleGetShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356330 uint32 immediate_data_size, const cmds::GetShaderSource& c) {
[email protected]df37b9932013-03-08 05:21:426331 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036332 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6333 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426334 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
6335 if (!shader || !shader->source()) {
[email protected]8eee29c2010-04-29 03:38:296336 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296337 return error::kNoError;
6338 }
[email protected]df37b9932013-03-08 05:21:426339 bucket->SetFromString(shader->source()->c_str());
[email protected]ae51d192010-04-27 00:48:036340 return error::kNoError;
6341}
6342
[email protected]d6a53e42011-10-05 00:09:366343error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6344 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:356345 const cmds::GetTranslatedShaderSourceANGLE& c) {
[email protected]df37b9932013-03-08 05:21:426346 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366347 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6348 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426349 Shader* shader = GetShaderInfoNotProgram(
6350 shader_id, "glTranslatedGetShaderSourceANGLE");
6351 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366352 bucket->SetSize(0);
6353 return error::kNoError;
6354 }
[email protected]df37b9932013-03-08 05:21:426355 ForceCompileShaderIfPending(shader);
[email protected]d6a53e42011-10-05 00:09:366356
[email protected]df37b9932013-03-08 05:21:426357 bucket->SetFromString(shader->translated_source() ?
6358 shader->translated_source()->c_str() : NULL);
[email protected]d6a53e42011-10-05 00:09:366359 return error::kNoError;
6360}
6361
[email protected]ae51d192010-04-27 00:48:036362error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356363 uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426364 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586365 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6366 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426367 Program* program = GetProgramInfoNotShader(
6368 program_id, "glGetProgramInfoLog");
6369 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466370 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036371 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316372 }
[email protected]df37b9932013-03-08 05:21:426373 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036374 return error::kNoError;
6375}
6376
6377error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356378 uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426379 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586380 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6381 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426382 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
6383 if (!shader || !shader->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466384 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036385 return error::kNoError;
6386 }
[email protected]df37b9932013-03-08 05:21:426387 bucket->SetFromString(shader->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036388 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326389}
6390
[email protected]d058bca2012-11-26 10:27:266391bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6392 return state_.GetEnabled(cap);
6393}
6394
[email protected]1958e0e2010-04-22 05:17:156395bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:216396 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106397 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156398}
6399
6400bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356401 const Framebuffer* framebuffer =
6402 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106403 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156404}
6405
6406bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366407 // IsProgram is true for programs as soon as they are created, until they are
6408 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:356409 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:106410 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156411}
6412
6413bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356414 const Renderbuffer* renderbuffer =
6415 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106416 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156417}
6418
6419bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366420 // IsShader is true for shaders as soon as they are created, until they
6421 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:356422 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:106423 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156424}
6425
6426bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:496427 const TextureRef* texture_ref = GetTexture(client_id);
6428 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:036429}
6430
6431void GLES2DecoderImpl::DoAttachShader(
6432 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426433 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586434 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:426435 if (!program) {
[email protected]ae51d192010-04-27 00:48:036436 return;
[email protected]1958e0e2010-04-22 05:17:156437 }
[email protected]df37b9932013-03-08 05:21:426438 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
6439 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036440 return;
6441 }
[email protected]df37b9932013-03-08 05:21:426442 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516443 LOCAL_SET_GL_ERROR(
6444 GL_INVALID_OPERATION,
6445 "glAttachShader",
6446 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:316447 return;
6448 }
[email protected]df37b9932013-03-08 05:21:426449 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036450}
6451
6452void GLES2DecoderImpl::DoDetachShader(
6453 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426454 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586455 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:426456 if (!program) {
[email protected]ae51d192010-04-27 00:48:036457 return;
6458 }
[email protected]df37b9932013-03-08 05:21:426459 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
6460 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036461 return;
6462 }
[email protected]df37b9932013-03-08 05:21:426463 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516464 LOCAL_SET_GL_ERROR(
6465 GL_INVALID_OPERATION,
6466 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:226467 return;
6468 }
[email protected]df37b9932013-03-08 05:21:426469 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036470}
6471
6472void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:426473 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586474 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:426475 if (!program) {
[email protected]ae51d192010-04-27 00:48:036476 return;
6477 }
[email protected]df37b9932013-03-08 05:21:426478 program->Validate();
[email protected]1958e0e2010-04-22 05:17:156479}
6480
[email protected]ac77603c72013-03-08 13:52:066481void GLES2DecoderImpl::GetVertexAttribHelper(
6482 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:246483 switch (pname) {
6484 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:066485 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:246486 if (buffer && !buffer->IsDeleted()) {
6487 GLuint client_id;
6488 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6489 *params = client_id;
6490 }
6491 break;
6492 }
6493 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:066494 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:246495 break;
6496 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:066497 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:246498 break;
6499 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:066500 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:246501 break;
6502 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:066503 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:246504 break;
6505 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:066506 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:246507 break;
[email protected]c6aef902012-02-14 03:31:426508 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:066509 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:426510 break;
[email protected]ac77603c72013-03-08 13:52:066511 default:
6512 NOTREACHED();
6513 break;
6514 }
6515}
6516
6517void GLES2DecoderImpl::DoGetVertexAttribfv(
6518 GLuint index, GLenum pname, GLfloat* params) {
6519 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6520 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516521 LOCAL_SET_GL_ERROR(
6522 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066523 return;
6524 }
6525 switch (pname) {
6526 case GL_CURRENT_VERTEX_ATTRIB: {
6527 const Vec4& value = state_.attrib_values[index];
6528 params[0] = value.v[0];
6529 params[1] = value.v[1];
6530 params[2] = value.v[2];
6531 params[3] = value.v[3];
6532 break;
6533 }
6534 default: {
6535 GLint value = 0;
6536 GetVertexAttribHelper(attrib, pname, &value);
6537 *params = static_cast<GLfloat>(value);
6538 break;
6539 }
6540 }
6541}
6542
6543void GLES2DecoderImpl::DoGetVertexAttribiv(
6544 GLuint index, GLenum pname, GLint* params) {
6545 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6546 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516547 LOCAL_SET_GL_ERROR(
6548 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066549 return;
6550 }
6551 switch (pname) {
[email protected]af6380962012-11-29 23:24:136552 case GL_CURRENT_VERTEX_ATTRIB: {
6553 const Vec4& value = state_.attrib_values[index];
6554 params[0] = static_cast<GLint>(value.v[0]);
6555 params[1] = static_cast<GLint>(value.v[1]);
6556 params[2] = static_cast<GLint>(value.v[2]);
6557 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:246558 break;
[email protected]af6380962012-11-29 23:24:136559 }
[email protected]b1122982010-05-17 23:04:246560 default:
[email protected]ac77603c72013-03-08 13:52:066561 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:246562 break;
6563 }
6564}
6565
[email protected]af6380962012-11-29 23:24:136566bool GLES2DecoderImpl::SetVertexAttribValue(
6567 const char* function_name, GLuint index, const GLfloat* value) {
6568 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:516569 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:136570 return false;
[email protected]b1122982010-05-17 23:04:246571 }
[email protected]af6380962012-11-29 23:24:136572 Vec4& v = state_.attrib_values[index];
6573 v.v[0] = value[0];
6574 v.v[1] = value[1];
6575 v.v[2] = value[2];
6576 v.v[3] = value[3];
6577 return true;
6578}
6579
6580void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
6581 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
6582 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
6583 glVertexAttrib1f(index, v0);
6584 }
[email protected]b1122982010-05-17 23:04:246585}
6586
6587void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:136588 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
6589 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
6590 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:246591 }
[email protected]b1122982010-05-17 23:04:246592}
6593
6594void GLES2DecoderImpl::DoVertexAttrib3f(
6595 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:136596 GLfloat v[4] = { v0, v1, v2, 1.0f, };
6597 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
6598 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:246599 }
[email protected]b1122982010-05-17 23:04:246600}
6601
6602void GLES2DecoderImpl::DoVertexAttrib4f(
6603 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:136604 GLfloat v[4] = { v0, v1, v2, v3, };
6605 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
6606 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:246607 }
[email protected]b1122982010-05-17 23:04:246608}
6609
6610void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136611 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
6612 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
6613 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:246614 }
[email protected]b1122982010-05-17 23:04:246615}
6616
6617void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136618 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
6619 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
6620 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:246621 }
[email protected]b1122982010-05-17 23:04:246622}
6623
6624void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136625 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
6626 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
6627 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:246628 }
[email protected]b1122982010-05-17 23:04:246629}
6630
6631void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136632 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
6633 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:246634 }
[email protected]b1122982010-05-17 23:04:246635}
6636
[email protected]f7a64ee2010-02-01 22:24:146637error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]ed9f9cd2013-02-27 21:12:356638 uint32 immediate_data_size, const cmds::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:466639
[email protected]e259eb412012-10-13 05:47:246640 if (!state_.bound_array_buffer || state_.bound_array_buffer->IsDeleted()) {
6641 if (state_.vertex_attrib_manager == default_vertex_attrib_manager_) {
[email protected]ab09b612013-03-11 22:11:516642 LOCAL_SET_GL_ERROR(
6643 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:466644 return error::kNoError;
6645 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:516646 LOCAL_SET_GL_ERROR(
6647 GL_INVALID_VALUE,
6648 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:466649 return error::kNoError;
6650 }
[email protected]96449d2c2009-11-25 00:01:326651 }
[email protected]8eee29c2010-04-29 03:38:296652
6653 GLuint indx = c.indx;
6654 GLint size = c.size;
6655 GLenum type = c.type;
6656 GLboolean normalized = c.normalized;
6657 GLsizei stride = c.stride;
6658 GLsizei offset = c.offset;
6659 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:056660 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516661 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:296662 return error::kNoError;
6663 }
[email protected]9438b012010-06-15 22:55:056664 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:516665 LOCAL_SET_GL_ERROR(
6666 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:296667 return error::kNoError;
6668 }
6669 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516670 LOCAL_SET_GL_ERROR(
6671 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:296672 return error::kNoError;
6673 }
6674 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:516675 LOCAL_SET_GL_ERROR(
6676 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:296677 return error::kNoError;
6678 }
6679 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:516680 LOCAL_SET_GL_ERROR(
6681 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:296682 return error::kNoError;
6683 }
6684 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516685 LOCAL_SET_GL_ERROR(
6686 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296687 return error::kNoError;
6688 }
6689 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:316690 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]8eee29c2010-04-29 03:38:296691 if (offset % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:516692 LOCAL_SET_GL_ERROR(
6693 GL_INVALID_OPERATION,
6694 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:316695 return error::kNoError;
6696 }
6697 if (stride % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:516698 LOCAL_SET_GL_ERROR(
6699 GL_INVALID_OPERATION,
6700 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:296701 return error::kNoError;
6702 }
[email protected]e259eb412012-10-13 05:47:246703 state_.vertex_attrib_manager->SetAttribInfo(
[email protected]8fbedc02010-11-18 18:43:406704 indx,
[email protected]e259eb412012-10-13 05:47:246705 state_.bound_array_buffer,
[email protected]8eee29c2010-04-29 03:38:296706 size,
6707 type,
[email protected]b1122982010-05-17 23:04:246708 normalized,
6709 stride,
6710 stride != 0 ? stride : component_size * size,
[email protected]8eee29c2010-04-29 03:38:296711 offset);
[email protected]8fbedc02010-11-18 18:43:406712 if (type != GL_FIXED) {
6713 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
6714 }
[email protected]f7a64ee2010-02-01 22:24:146715 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326716}
6717
[email protected]43410e92012-04-20 17:06:286718void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
6719 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:246720 state_.viewport_x = x;
6721 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:026722 state_.viewport_width = std::min(width, viewport_max_width_);
6723 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:286724 glViewport(x, y, width, height);
6725}
6726
[email protected]c6aef902012-02-14 03:31:426727error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356728 uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156729 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516730 LOCAL_SET_GL_ERROR(
6731 GL_INVALID_OPERATION,
6732 "glVertexAttribDivisorANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426733 }
6734 GLuint index = c.index;
6735 GLuint divisor = c.divisor;
6736 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516737 LOCAL_SET_GL_ERROR(
6738 GL_INVALID_VALUE,
6739 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:426740 return error::kNoError;
6741 }
6742
[email protected]e259eb412012-10-13 05:47:246743 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:426744 index,
6745 divisor);
6746 glVertexAttribDivisorANGLE(index, divisor);
6747 return error::kNoError;
6748}
6749
[email protected]f7a64ee2010-02-01 22:24:146750error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]ed9f9cd2013-02-27 21:12:356751 uint32 immediate_data_size, const cmds::ReadPixels& c) {
[email protected]09e17272012-11-30 10:30:446752 if (ShouldDeferReads())
6753 return error::kDeferCommandUntilLater;
[email protected]612d2f82009-12-08 20:49:316754 GLint x = c.x;
6755 GLint y = c.y;
6756 GLsizei width = c.width;
6757 GLsizei height = c.height;
6758 GLenum format = c.format;
6759 GLenum type = c.type;
[email protected]57f223832010-03-19 01:57:566760 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:516761 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:566762 return error::kNoError;
6763 }
[email protected]ed9f9cd2013-02-27 21:12:356764 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:186765 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:346766 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246767 width, height, format, type, state_.pack_alignment, &pixels_size,
6768 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:186769 return error::kOutOfBounds;
6770 }
[email protected]612d2f82009-12-08 20:49:316771 void* pixels = GetSharedMemoryAs<void*>(
6772 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:106773 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:146774 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:466775 }
[email protected]de43f082013-04-02 01:16:106776 Result* result = NULL;
6777 if (c.result_shm_id != 0) {
6778 result = GetSharedMemoryAs<Result*>(
6779 c.result_shm_id, c.result_shm_offset, sizeof(*result));
6780 if (!result) {
6781 return error::kOutOfBounds;
6782 }
6783 }
[email protected]a51788e2010-02-24 21:54:256784
[email protected]9438b012010-06-15 22:55:056785 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:516786 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:296787 return error::kNoError;
6788 }
[email protected]9438b012010-06-15 22:55:056789 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516790 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:126791 return error::kNoError;
6792 }
[email protected]57f223832010-03-19 01:57:566793 if (width == 0 || height == 0) {
6794 return error::kNoError;
6795 }
6796
[email protected]57f223832010-03-19 01:57:566797 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:306798 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:566799
[email protected]3aad1a32012-09-07 20:54:476800 int32 max_x;
6801 int32 max_y;
6802 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:516803 LOCAL_SET_GL_ERROR(
6804 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:146805 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:316806 }
[email protected]57f223832010-03-19 01:57:566807
[email protected]0d6bfdc2011-11-02 01:32:206808 if (!CheckBoundFramebuffersValid("glReadPixels")) {
6809 return error::kNoError;
6810 }
6811
[email protected]ab09b612013-03-11 22:11:516812 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixel");
[email protected]a0b78dc2011-11-11 10:43:106813
6814 ScopedResolvedFrameBufferBinder binder(this, false, true);
6815
[email protected]d37231fa2010-04-09 21:16:026816 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:566817 // The user requested an out of range area. Get the results 1 line
6818 // at a time.
6819 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346820 uint32 unpadded_row_size;
6821 uint32 padded_row_size;
6822 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246823 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346824 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:516825 LOCAL_SET_GL_ERROR(
6826 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566827 return error::kNoError;
6828 }
6829
6830 GLint dest_x_offset = std::max(-x, 0);
6831 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:346832 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246833 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
6834 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:516835 LOCAL_SET_GL_ERROR(
6836 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566837 return error::kNoError;
6838 }
6839
6840 // Copy each row into the larger dest rect.
6841 int8* dst = static_cast<int8*>(pixels);
6842 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:026843 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:566844 GLint read_width = read_end_x - read_x;
6845 for (GLint yy = 0; yy < height; ++yy) {
6846 GLint ry = y + yy;
6847
6848 // Clear the row.
6849 memset(dst, 0, unpadded_row_size);
6850
6851 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:026852 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:566853 glReadPixels(
6854 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
6855 }
6856 dst += padded_row_size;
6857 }
6858 } else {
6859 glReadPixels(x, y, width, height, format, type, pixels);
6860 }
[email protected]ab09b612013-03-11 22:11:516861 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:256862 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:106863 if (result != NULL) {
6864 *result = true;
6865 }
[email protected]4848b9f82011-03-10 18:37:566866
6867 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
6868 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
[email protected]84eb4252012-06-29 22:56:446869 if ((channels_exist & 0x0008) == 0 &&
[email protected]62e155e2012-10-23 22:43:156870 workarounds().clear_alpha_in_readpixels) {
[email protected]4848b9f82011-03-10 18:37:566871 // Set the alpha to 255 because some drivers are buggy in this regard.
6872 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346873
6874 uint32 unpadded_row_size;
6875 uint32 padded_row_size;
6876 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246877 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346878 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:516879 LOCAL_SET_GL_ERROR(
6880 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]4848b9f82011-03-10 18:37:566881 return error::kNoError;
6882 }
6883 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time
6884 // of this implementation.
6885 if (type != GL_UNSIGNED_BYTE) {
[email protected]ab09b612013-03-11 22:11:516886 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436887 GL_INVALID_OPERATION, "glReadPixels",
6888 "unsupported readPixel format");
[email protected]4848b9f82011-03-10 18:37:566889 return error::kNoError;
6890 }
6891 switch (format) {
6892 case GL_RGBA:
[email protected]297ca1c2011-06-20 23:08:466893 case GL_BGRA_EXT:
[email protected]4848b9f82011-03-10 18:37:566894 case GL_ALPHA: {
6895 int offset = (format == GL_ALPHA) ? 0 : 3;
6896 int step = (format == GL_ALPHA) ? 1 : 4;
6897 uint8* dst = static_cast<uint8*>(pixels) + offset;
6898 for (GLint yy = 0; yy < height; ++yy) {
6899 uint8* end = dst + unpadded_row_size;
6900 for (uint8* d = dst; d < end; d += step) {
6901 *d = 255;
6902 }
6903 dst += padded_row_size;
6904 }
6905 break;
6906 }
6907 default:
6908 break;
6909 }
6910 }
[email protected]a51788e2010-02-24 21:54:256911 }
[email protected]4848b9f82011-03-10 18:37:566912
[email protected]f7a64ee2010-02-01 22:24:146913 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326914}
6915
[email protected]f7a64ee2010-02-01 22:24:146916error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]ed9f9cd2013-02-27 21:12:356917 uint32 immediate_data_size, const cmds::PixelStorei& c) {
[email protected]b9849abf2009-11-25 19:13:196918 GLenum pname = c.pname;
6919 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:056920 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:516921 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:126922 return error::kNoError;
6923 }
[email protected]222471d2011-11-30 18:06:396924 switch (pname) {
6925 case GL_PACK_ALIGNMENT:
6926 case GL_UNPACK_ALIGNMENT:
6927 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:516928 LOCAL_SET_GL_ERROR(
6929 GL_INVALID_VALUE, "glPixelStore", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:396930 return error::kNoError;
6931 }
[email protected]164d6d52012-05-05 00:55:036932 break;
[email protected]0a1e9ad2012-05-04 21:13:036933 case GL_UNPACK_FLIP_Y_CHROMIUM:
6934 unpack_flip_y_ = (param != 0);
6935 return error::kNoError;
6936 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
6937 unpack_premultiply_alpha_ = (param != 0);
6938 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:176939 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
6940 unpack_unpremultiply_alpha_ = (param != 0);
6941 return error::kNoError;
[email protected]222471d2011-11-30 18:06:396942 default:
6943 break;
[email protected]b9849abf2009-11-25 19:13:196944 }
6945 glPixelStorei(pname, param);
6946 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:436947 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246948 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436949 break;
6950 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:426951 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:436952 break;
6953 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246954 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436955 break;
6956 default:
6957 // Validation should have prevented us from getting here.
6958 NOTREACHED();
6959 break;
[email protected]b9849abf2009-11-25 19:13:196960 }
[email protected]f7a64ee2010-02-01 22:24:146961 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196962}
6963
[email protected]1c75a3702011-11-11 14:15:286964error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:356965 uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:386966 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]6f5fac9d12012-06-26 21:02:456967 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) {
[email protected]ab09b612013-03-11 22:11:516968 LOCAL_SET_GL_ERROR(
6969 GL_INVALID_OPERATION,
6970 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:286971 return error::kNoError;
6972 }
[email protected]7794d512012-04-17 20:36:496973 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:286974 return error::kNoError;
[email protected]7794d512012-04-17 20:36:496975 } else {
6976 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:286977 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:496978 }
[email protected]1c75a3702011-11-11 14:15:286979}
6980
[email protected]558847a2010-03-24 07:02:546981error::Error GLES2DecoderImpl::GetAttribLocationHelper(
6982 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
6983 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:576984 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:516985 LOCAL_SET_GL_ERROR(
6986 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:576987 return error::kNoError;
6988 }
[email protected]df37b9932013-03-08 05:21:426989 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586990 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:426991 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:146992 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196993 }
[email protected]df37b9932013-03-08 05:21:426994 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:516995 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436996 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:256997 return error::kNoError;
6998 }
[email protected]b9849abf2009-11-25 19:13:196999 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547000 location_shm_id, location_shm_offset, sizeof(GLint));
7001 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147002 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197003 }
[email protected]558847a2010-03-24 07:02:547004 // Require the client to init this incase the context is lost and we are no
7005 // longer executing commands.
7006 if (*location != -1) {
7007 return error::kGenericError;
7008 }
[email protected]df37b9932013-03-08 05:21:427009 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147010 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197011}
7012
[email protected]558847a2010-03-24 07:02:547013error::Error GLES2DecoderImpl::HandleGetAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:357014 uint32 immediate_data_size, const cmds::GetAttribLocation& c) {
[email protected]558847a2010-03-24 07:02:547015 uint32 name_size = c.data_size;
7016 const char* name = GetSharedMemoryAs<const char*>(
7017 c.name_shm_id, c.name_shm_offset, name_size);
7018 if (!name) {
7019 return error::kOutOfBounds;
7020 }
7021 String name_str(name, name_size);
7022 return GetAttribLocationHelper(
7023 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7024}
7025
[email protected]f7a64ee2010-02-01 22:24:147026error::Error GLES2DecoderImpl::HandleGetAttribLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357027 uint32 immediate_data_size, const cmds::GetAttribLocationImmediate& c) {
[email protected]558847a2010-03-24 07:02:547028 uint32 name_size = c.data_size;
7029 const char* name = GetImmediateDataAs<const char*>(
7030 c, name_size, immediate_data_size);
7031 if (!name) {
7032 return error::kOutOfBounds;
7033 }
7034 String name_str(name, name_size);
7035 return GetAttribLocationHelper(
7036 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7037}
7038
7039error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357040 uint32 immediate_data_size, const cmds::GetAttribLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547041 Bucket* bucket = GetBucket(c.name_bucket_id);
7042 if (!bucket) {
7043 return error::kInvalidArguments;
7044 }
7045 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187046 if (!bucket->GetAsString(&name_str)) {
7047 return error::kInvalidArguments;
7048 }
[email protected]558847a2010-03-24 07:02:547049 return GetAttribLocationHelper(
7050 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7051}
7052
7053error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7054 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7055 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577056 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517057 LOCAL_SET_GL_ERROR(
7058 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577059 return error::kNoError;
7060 }
[email protected]df37b9932013-03-08 05:21:427061 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587062 client_id, "glUniformLocation");
[email protected]df37b9932013-03-08 05:21:427063 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147064 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197065 }
[email protected]df37b9932013-03-08 05:21:427066 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517067 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437068 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257069 return error::kNoError;
7070 }
[email protected]b9849abf2009-11-25 19:13:197071 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547072 location_shm_id, location_shm_offset, sizeof(GLint));
7073 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147074 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197075 }
[email protected]558847a2010-03-24 07:02:547076 // Require the client to init this incase the context is lost an we are no
7077 // longer executing commands.
7078 if (*location != -1) {
7079 return error::kGenericError;
7080 }
[email protected]df37b9932013-03-08 05:21:427081 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147082 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197083}
7084
[email protected]f7a64ee2010-02-01 22:24:147085error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]ed9f9cd2013-02-27 21:12:357086 uint32 immediate_data_size, const cmds::GetUniformLocation& c) {
[email protected]b9849abf2009-11-25 19:13:197087 uint32 name_size = c.data_size;
7088 const char* name = GetSharedMemoryAs<const char*>(
7089 c.name_shm_id, c.name_shm_offset, name_size);
[email protected]558847a2010-03-24 07:02:547090 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147091 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197092 }
7093 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547094 return GetUniformLocationHelper(
7095 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197096}
7097
[email protected]f7a64ee2010-02-01 22:24:147098error::Error GLES2DecoderImpl::HandleGetUniformLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357099 uint32 immediate_data_size, const cmds::GetUniformLocationImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197100 uint32 name_size = c.data_size;
[email protected]07f54fcc2009-12-22 02:46:307101 const char* name = GetImmediateDataAs<const char*>(
7102 c, name_size, immediate_data_size);
[email protected]558847a2010-03-24 07:02:547103 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147104 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197105 }
7106 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547107 return GetUniformLocationHelper(
7108 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7109}
7110
7111error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357112 uint32 immediate_data_size, const cmds::GetUniformLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547113 Bucket* bucket = GetBucket(c.name_bucket_id);
7114 if (!bucket) {
7115 return error::kInvalidArguments;
7116 }
7117 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187118 if (!bucket->GetAsString(&name_str)) {
7119 return error::kInvalidArguments;
7120 }
[email protected]558847a2010-03-24 07:02:547121 return GetUniformLocationHelper(
7122 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197123}
7124
[email protected]ddd968b82010-03-02 00:44:297125error::Error GLES2DecoderImpl::HandleGetString(
[email protected]ed9f9cd2013-02-27 21:12:357126 uint32 immediate_data_size, const cmds::GetString& c) {
[email protected]ddd968b82010-03-02 00:44:297127 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057128 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517129 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297130 return error::kNoError;
7131 }
[email protected]1958e0e2010-04-22 05:17:157132 const char* gl_str = reinterpret_cast<const char*>(glGetString(name));
7133 const char* str = NULL;
[email protected]f0d74742011-10-03 16:31:047134 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157135 switch (name) {
7136 case GL_VERSION:
7137 str = "OpenGL ES 2.0 Chromium";
7138 break;
7139 case GL_SHADING_LANGUAGE_VERSION:
7140 str = "OpenGL ES GLSL ES 1.0 Chromium";
7141 break;
[email protected]32939602012-05-09 06:25:167142 case GL_RENDERER:
7143 str = "Chromium";
7144 break;
7145 case GL_VENDOR:
7146 str = "Chromium";
7147 break;
[email protected]1958e0e2010-04-22 05:17:157148 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047149 {
7150 // For WebGL contexts, strip out the OES derivatives extension if it has
7151 // not been enabled.
7152 if (force_webgl_glsl_validation_ &&
7153 !derivatives_explicitly_enabled_) {
7154 extensions = feature_info_->extensions();
7155 size_t offset = extensions.find(kOESDerivativeExtension);
7156 if (std::string::npos != offset) {
7157 extensions.replace(offset,
7158 offset + arraysize(kOESDerivativeExtension),
7159 std::string());
7160 }
[email protected]f0d74742011-10-03 16:31:047161 } else {
[email protected]6f5fac9d12012-06-26 21:02:457162 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047163 }
[email protected]6f5fac9d12012-06-26 21:02:457164 std::string surface_extensions = surface_->GetExtensions();
7165 if (!surface_extensions.empty())
7166 extensions += " " + surface_extensions;
7167 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047168 }
[email protected]1958e0e2010-04-22 05:17:157169 break;
7170 default:
7171 str = gl_str;
7172 break;
7173 }
[email protected]ddd968b82010-03-02 00:44:297174 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157175 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297176 return error::kNoError;
7177}
7178
[email protected]0c86dbf2010-03-05 08:14:117179void GLES2DecoderImpl::DoBufferData(
[email protected]b9363b22010-06-09 22:06:157180 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) {
[email protected]9438b012010-06-15 22:55:057181 if (!validators_->buffer_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517182 LOCAL_SET_GL_ERROR_INVALID_ENUM("glBufferData", target, "target");
[email protected]8eee29c2010-04-29 03:38:297183 return;
7184 }
[email protected]9438b012010-06-15 22:55:057185 if (!validators_->buffer_usage.IsValid(usage)) {
[email protected]ab09b612013-03-11 22:11:517186 LOCAL_SET_GL_ERROR_INVALID_ENUM("glBufferData", usage, "usage");
[email protected]0c86dbf2010-03-05 08:14:117187 return;
[email protected]3b6ec202010-03-05 05:16:237188 }
7189 if (size < 0) {
[email protected]ab09b612013-03-11 22:11:517190 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferData", "size < 0");
[email protected]037896bd2010-04-21 19:07:287191 return;
[email protected]3b6ec202010-03-05 05:16:237192 }
[email protected]17cfbe0e2013-03-07 01:26:087193 Buffer* buffer = GetBufferInfoForTarget(target);
7194 if (!buffer) {
[email protected]ab09b612013-03-11 22:11:517195 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:287196 return;
[email protected]3b6ec202010-03-05 05:16:237197 }
[email protected]7989c9e2013-01-23 06:39:267198
7199 if (!EnsureGPUMemoryAvailable(size)) {
[email protected]ab09b612013-03-11 22:11:517200 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glBufferData", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267201 return;
7202 }
7203
[email protected]d3eba342013-04-18 21:11:507204 buffer_manager()->DoBufferData(GetErrorState(), buffer, size, usage, data);
[email protected]0c86dbf2010-03-05 08:14:117205}
7206
7207error::Error GLES2DecoderImpl::HandleBufferData(
[email protected]ed9f9cd2013-02-27 21:12:357208 uint32 immediate_data_size, const cmds::BufferData& c) {
[email protected]0c86dbf2010-03-05 08:14:117209 GLenum target = static_cast<GLenum>(c.target);
7210 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7211 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7212 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7213 GLenum usage = static_cast<GLenum>(c.usage);
7214 const void* data = NULL;
7215 if (data_shm_id != 0 || data_shm_offset != 0) {
7216 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7217 if (!data) {
7218 return error::kOutOfBounds;
7219 }
7220 }
7221 DoBufferData(target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147222 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197223}
7224
[email protected]f7a64ee2010-02-01 22:24:147225error::Error GLES2DecoderImpl::HandleBufferDataImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357226 uint32 immediate_data_size, const cmds::BufferDataImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197227 GLenum target = static_cast<GLenum>(c.target);
7228 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
[email protected]07f54fcc2009-12-22 02:46:307229 const void* data = GetImmediateDataAs<const void*>(
7230 c, size, immediate_data_size);
7231 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147232 return error::kOutOfBounds;
[email protected]07f54fcc2009-12-22 02:46:307233 }
[email protected]b9849abf2009-11-25 19:13:197234 GLenum usage = static_cast<GLenum>(c.usage);
[email protected]0c86dbf2010-03-05 08:14:117235 DoBufferData(target, size, data, usage);
7236 return error::kNoError;
7237}
7238
7239void GLES2DecoderImpl::DoBufferSubData(
7240 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]17cfbe0e2013-03-07 01:26:087241 Buffer* buffer = GetBufferInfoForTarget(target);
7242 if (!buffer) {
[email protected]ab09b612013-03-11 22:11:517243 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:287244 return;
[email protected]a93bb842010-02-16 23:03:477245 }
[email protected]17cfbe0e2013-03-07 01:26:087246
[email protected]d3eba342013-04-18 21:11:507247 buffer_manager()->DoBufferSubData(GetErrorState(), buffer, offset, size,
7248 data);
[email protected]b9849abf2009-11-25 19:13:197249}
7250
[email protected]0d6bfdc2011-11-02 01:32:207251bool GLES2DecoderImpl::ClearLevel(
7252 unsigned service_id,
7253 unsigned bind_target,
7254 unsigned target,
7255 int level,
7256 unsigned format,
7257 unsigned type,
7258 int width,
[email protected]4502e6492011-12-14 19:39:157259 int height,
7260 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007261 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7262 if (IsAngle() && (channels & GLES2Util::kDepth) != 0) {
7263 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7264 // on depth formats.
7265 GLuint fb = 0;
7266 glGenFramebuffersEXT(1, &fb);
7267 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7268
7269 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7270 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7271 GL_DEPTH_ATTACHMENT;
7272
7273 glFramebufferTexture2DEXT(
7274 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7275 // ANGLE promises a depth only attachment ok.
7276 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7277 GL_FRAMEBUFFER_COMPLETE) {
7278 return false;
7279 }
7280 glClearStencil(0);
7281 glStencilMask(-1);
7282 glClearDepth(1.0f);
7283 glDepthMask(true);
7284 glDisable(GL_SCISSOR_TEST);
7285 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7286
7287 RestoreClearState();
7288
7289 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:357290 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:007291 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7292 GLuint fb_service_id =
7293 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7294 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7295 return true;
7296 }
7297
[email protected]45d15a62012-04-18 14:33:177298 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7299
7300 uint32 size;
7301 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:347302 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247303 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:177304 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:207305 return false;
7306 }
[email protected]45d15a62012-04-18 14:33:177307
[email protected]a5d3dad2012-05-26 04:34:447308 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7309
[email protected]45d15a62012-04-18 14:33:177310 int tile_height;
7311
7312 if (size > kMaxZeroSize) {
7313 if (kMaxZeroSize < padded_row_size) {
7314 // That'd be an awfully large texture.
7315 return false;
7316 }
7317 // We should never have a large total size with a zero row size.
7318 DCHECK_GT(padded_row_size, 0U);
7319 tile_height = kMaxZeroSize / padded_row_size;
7320 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247321 width, tile_height, format, type, state_.unpack_alignment, &size,
7322 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:177323 return false;
7324 }
[email protected]4502e6492011-12-14 19:39:157325 } else {
[email protected]45d15a62012-04-18 14:33:177326 tile_height = height;
7327 }
7328
7329 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:557330 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:177331 memset(zero.get(), 0, size);
7332 glBindTexture(bind_target, service_id);
7333
7334 GLint y = 0;
7335 while (y < height) {
7336 GLint h = y + tile_height > height ? height - y : tile_height;
7337 if (is_texture_immutable || h != height) {
7338 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7339 } else {
[email protected]8f1d2aa2013-05-10 23:45:387340 glTexImage2D(
[email protected]45d15a62012-04-18 14:33:177341 target, level, format, width, h, 0, format, type, zero.get());
7342 }
7343 y += tile_height;
[email protected]4502e6492011-12-14 19:39:157344 }
[email protected]370eaf12013-05-18 09:19:497345 TextureRef* texture = GetTextureInfoForTarget(bind_target);
[email protected]02965c22013-03-09 02:40:077346 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:207347 return true;
7348}
7349
[email protected]ad84a3a2012-06-08 21:42:437350namespace {
7351
7352const int kS3TCBlockWidth = 4;
7353const int kS3TCBlockHeight = 4;
7354const int kS3TCDXT1BlockSize = 8;
7355const int kS3TCDXT3AndDXT5BlockSize = 16;
[email protected]2d3765b2012-10-03 00:31:077356const int kETC1BlockWidth = 4;
7357const int kETC1BlockHeight = 4;
7358const int kETC1BlockSize = 8;
[email protected]ad84a3a2012-06-08 21:42:437359
7360bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:517361 return (size == 1) ||
7362 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:437363}
7364
7365} // anonymous namespace.
7366
7367bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7368 const char* function_name,
7369 GLsizei width, GLsizei height, GLenum format, size_t size) {
7370 unsigned int bytes_required = 0;
7371
7372 switch (format) {
7373 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7374 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: {
7375 int num_blocks_across =
7376 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7377 int num_blocks_down =
7378 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7379 int num_blocks = num_blocks_across * num_blocks_down;
7380 bytes_required = num_blocks * kS3TCDXT1BlockSize;
7381 break;
7382 }
7383 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7384 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7385 int num_blocks_across =
7386 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7387 int num_blocks_down =
7388 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7389 int num_blocks = num_blocks_across * num_blocks_down;
7390 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
7391 break;
7392 }
[email protected]2d3765b2012-10-03 00:31:077393 case GL_ETC1_RGB8_OES: {
7394 int num_blocks_across =
7395 (width + kETC1BlockWidth - 1) / kETC1BlockWidth;
7396 int num_blocks_down =
7397 (height + kETC1BlockHeight - 1) / kETC1BlockHeight;
7398 int num_blocks = num_blocks_across * num_blocks_down;
7399 bytes_required = num_blocks * kETC1BlockSize;
7400 break;
7401 }
[email protected]ad84a3a2012-06-08 21:42:437402 default:
[email protected]ab09b612013-03-11 22:11:517403 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:437404 return false;
7405 }
7406
7407 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:517408 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437409 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
7410 return false;
7411 }
7412
7413 return true;
7414}
7415
7416bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
7417 const char* function_name,
7418 GLint level, GLsizei width, GLsizei height, GLenum format) {
7419 switch (format) {
7420 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7421 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7422 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7423 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7424 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:517425 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437426 GL_INVALID_OPERATION, function_name,
7427 "width or height invalid for level");
7428 return false;
7429 }
7430 return true;
7431 }
[email protected]2d3765b2012-10-03 00:31:077432 case GL_ETC1_RGB8_OES:
7433 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:517434 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077435 GL_INVALID_OPERATION, function_name,
7436 "width or height invalid for level");
7437 return false;
7438 }
7439 return true;
[email protected]ad84a3a2012-06-08 21:42:437440 default:
7441 return false;
7442 }
7443}
7444
7445bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
7446 const char* function_name,
7447 GLenum target, GLint level, GLint xoffset, GLint yoffset,
7448 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:357449 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:437450 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:517451 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437452 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
7453 return false;
7454 }
7455
7456 switch (format) {
7457 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7458 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7459 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7460 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7461 const int kBlockWidth = 4;
7462 const int kBlockHeight = 4;
7463 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:517464 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437465 GL_INVALID_OPERATION, function_name,
7466 "xoffset or yoffset not multiple of 4");
7467 return false;
7468 }
7469 GLsizei tex_width = 0;
7470 GLsizei tex_height = 0;
7471 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
7472 width - xoffset > tex_width ||
7473 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:517474 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437475 GL_INVALID_OPERATION, function_name, "dimensions out of range");
7476 return false;
7477 }
7478 return ValidateCompressedTexDimensions(
7479 function_name, level, width, height, format);
7480 }
[email protected]2d3765b2012-10-03 00:31:077481 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:517482 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077483 GL_INVALID_OPERATION, function_name,
7484 "TexsubImage2d not supported for ECT1_RGB8_OES textures");
7485 return false;
7486 }
[email protected]ad84a3a2012-06-08 21:42:437487 default:
7488 return false;
7489 }
7490}
7491
[email protected]a93bb842010-02-16 23:03:477492error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
7493 GLenum target,
7494 GLint level,
7495 GLenum internal_format,
7496 GLsizei width,
7497 GLsizei height,
7498 GLint border,
7499 GLsizei image_size,
7500 const void* data) {
[email protected]a93bb842010-02-16 23:03:477501 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:057502 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517503 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7504 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297505 return error::kNoError;
7506 }
[email protected]9438b012010-06-15 22:55:057507 if (!validators_->compressed_texture_format.IsValid(
7508 internal_format)) {
[email protected]ab09b612013-03-11 22:11:517509 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:537510 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:477511 return error::kNoError;
7512 }
[email protected]80eb6b52012-01-19 00:14:417513 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477514 border != 0) {
[email protected]ab09b612013-03-11 22:11:517515 LOCAL_SET_GL_ERROR(
7516 GL_INVALID_VALUE,
7517 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:477518 return error::kNoError;
7519 }
[email protected]370eaf12013-05-18 09:19:497520 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7521 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517522 LOCAL_SET_GL_ERROR(
7523 GL_INVALID_VALUE,
7524 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:477525 return error::kNoError;
7526 }
[email protected]370eaf12013-05-18 09:19:497527 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:077528 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517529 LOCAL_SET_GL_ERROR(
7530 GL_INVALID_OPERATION,
7531 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:437532 return error::kNoError;
7533 }
7534
7535 if (!ValidateCompressedTexDimensions(
7536 "glCompressedTexImage2D", level, width, height, internal_format) ||
7537 !ValidateCompressedTexFuncData(
7538 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:177539 return error::kNoError;
7540 }
[email protected]968351b2011-12-20 08:26:517541
[email protected]7989c9e2013-01-23 06:39:267542 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:517543 LOCAL_SET_GL_ERROR(
7544 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267545 return error::kNoError;
7546 }
7547
[email protected]02965c22013-03-09 02:40:077548 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427549 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517550 }
7551
[email protected]40d90a22013-04-09 03:39:557552 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:477553 if (!data) {
7554 zero.reset(new int8[image_size]);
7555 memset(zero.get(), 0, image_size);
7556 data = zero.get();
7557 }
[email protected]ab09b612013-03-11 22:11:517558 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:477559 glCompressedTexImage2D(
7560 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:517561 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:437562 if (error == GL_NO_ERROR) {
7563 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497564 texture_ref, target, level, internal_format,
7565 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:437566 }
[email protected]a93bb842010-02-16 23:03:477567 return error::kNoError;
7568}
7569
[email protected]f7a64ee2010-02-01 22:24:147570error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357571 uint32 immediate_data_size, const cmds::CompressedTexImage2D& c) {
[email protected]b9849abf2009-11-25 19:13:197572 GLenum target = static_cast<GLenum>(c.target);
7573 GLint level = static_cast<GLint>(c.level);
7574 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7575 GLsizei width = static_cast<GLsizei>(c.width);
7576 GLsizei height = static_cast<GLsizei>(c.height);
7577 GLint border = static_cast<GLint>(c.border);
7578 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
7579 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7580 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7581 const void* data = NULL;
7582 if (data_shm_id != 0 || data_shm_offset != 0) {
7583 data = GetSharedMemoryAs<const void*>(
7584 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:467585 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147586 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197587 }
7588 }
[email protected]a93bb842010-02-16 23:03:477589 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197590 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:197591}
7592
[email protected]f7a64ee2010-02-01 22:24:147593error::Error GLES2DecoderImpl::HandleCompressedTexImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357594 uint32 immediate_data_size, const cmds::CompressedTexImage2DImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197595 GLenum target = static_cast<GLenum>(c.target);
7596 GLint level = static_cast<GLint>(c.level);
7597 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7598 GLsizei width = static_cast<GLsizei>(c.width);
7599 GLsizei height = static_cast<GLsizei>(c.height);
7600 GLint border = static_cast<GLint>(c.border);
7601 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
[email protected]07f54fcc2009-12-22 02:46:307602 const void* data = GetImmediateDataAs<const void*>(
7603 c, image_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467604 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147605 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467606 }
[email protected]a93bb842010-02-16 23:03:477607 return DoCompressedTexImage2D(
7608 target, level, internal_format, width, height, border, image_size, data);
7609}
7610
[email protected]b6140d02010-05-17 14:47:167611error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
[email protected]ed9f9cd2013-02-27 21:12:357612 uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167613 GLenum target = static_cast<GLenum>(c.target);
7614 GLint level = static_cast<GLint>(c.level);
7615 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7616 GLsizei width = static_cast<GLsizei>(c.width);
7617 GLsizei height = static_cast<GLsizei>(c.height);
7618 GLint border = static_cast<GLint>(c.border);
7619 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287620 if (!bucket) {
7621 return error::kInvalidArguments;
7622 }
7623 uint32 data_size = bucket->size();
7624 GLsizei imageSize = data_size;
7625 const void* data = bucket->GetData(0, data_size);
7626 if (!data) {
7627 return error::kInvalidArguments;
7628 }
[email protected]b6140d02010-05-17 14:47:167629 return DoCompressedTexImage2D(
7630 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:287631 imageSize, data);
[email protected]b6140d02010-05-17 14:47:167632}
7633
7634error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
7635 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:357636 const cmds::CompressedTexSubImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167637 GLenum target = static_cast<GLenum>(c.target);
7638 GLint level = static_cast<GLint>(c.level);
7639 GLint xoffset = static_cast<GLint>(c.xoffset);
7640 GLint yoffset = static_cast<GLint>(c.yoffset);
7641 GLsizei width = static_cast<GLsizei>(c.width);
7642 GLsizei height = static_cast<GLsizei>(c.height);
7643 GLenum format = static_cast<GLenum>(c.format);
7644 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287645 if (!bucket) {
7646 return error::kInvalidArguments;
7647 }
[email protected]b6140d02010-05-17 14:47:167648 uint32 data_size = bucket->size();
7649 GLsizei imageSize = data_size;
7650 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:287651 if (!data) {
7652 return error::kInvalidArguments;
7653 }
[email protected]9438b012010-06-15 22:55:057654 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517655 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:537656 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:167657 return error::kNoError;
7658 }
[email protected]9438b012010-06-15 22:55:057659 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517660 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7661 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:057662 return error::kNoError;
7663 }
[email protected]b6140d02010-05-17 14:47:167664 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:517665 LOCAL_SET_GL_ERROR(
7666 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:167667 return error::kNoError;
7668 }
7669 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:517670 LOCAL_SET_GL_ERROR(
7671 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:167672 return error::kNoError;
7673 }
7674 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:517675 LOCAL_SET_GL_ERROR(
7676 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:167677 return error::kNoError;
7678 }
[email protected]cadde4a2010-07-31 17:10:437679 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:167680 target, level, xoffset, yoffset, width, height, format, imageSize, data);
7681 return error::kNoError;
7682}
7683
[email protected]81375742012-06-08 00:04:007684bool GLES2DecoderImpl::ValidateTextureParameters(
7685 const char* function_name,
7686 GLenum target, GLenum format, GLenum type, GLint level) {
7687 if (!feature_info_->GetTextureFormatValidator(format).IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517688 LOCAL_SET_GL_ERROR(
7689 GL_INVALID_OPERATION, function_name,
7690 (std::string("invalid type ") +
7691 GLES2Util::GetStringEnum(type) + " for format " +
7692 GLES2Util::GetStringEnum(format)).c_str());
[email protected]81375742012-06-08 00:04:007693 return false;
7694 }
7695
7696 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7697 if ((channels & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && level) {
[email protected]ab09b612013-03-11 22:11:517698 LOCAL_SET_GL_ERROR(
7699 GL_INVALID_OPERATION, function_name,
7700 (std::string("invalid type ") +
7701 GLES2Util::GetStringEnum(type) + " for format " +
7702 GLES2Util::GetStringEnum(format)).c_str());
[email protected]81375742012-06-08 00:04:007703 return false;
7704 }
7705 return true;
7706}
7707
[email protected]f598f422012-12-07 08:30:037708bool GLES2DecoderImpl::ValidateTexImage2D(
7709 const char* function_name,
7710 GLenum target,
7711 GLint level,
7712 GLenum internal_format,
7713 GLsizei width,
7714 GLsizei height,
7715 GLint border,
7716 GLenum format,
7717 GLenum type,
7718 const void* pixels,
7719 uint32 pixels_size) {
[email protected]9438b012010-06-15 22:55:057720 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517721 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:037722 return false;
[email protected]8eee29c2010-04-29 03:38:297723 }
[email protected]9438b012010-06-15 22:55:057724 if (!validators_->texture_format.IsValid(internal_format)) {
[email protected]ab09b612013-03-11 22:11:517725 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7726 function_name, internal_format, "internal_format");
[email protected]f598f422012-12-07 08:30:037727 return false;
[email protected]8eee29c2010-04-29 03:38:297728 }
[email protected]9438b012010-06-15 22:55:057729 if (!validators_->texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517730 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]f598f422012-12-07 08:30:037731 return false;
[email protected]8eee29c2010-04-29 03:38:297732 }
[email protected]9438b012010-06-15 22:55:057733 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517734 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]f598f422012-12-07 08:30:037735 return false;
[email protected]b9849abf2009-11-25 19:13:197736 }
[email protected]7b92c412010-07-20 17:48:257737 if (format != internal_format) {
[email protected]ab09b612013-03-11 22:11:517738 LOCAL_SET_GL_ERROR(
7739 GL_INVALID_OPERATION, function_name, "format != internalFormat");
[email protected]f598f422012-12-07 08:30:037740 return false;
[email protected]7b92c412010-07-20 17:48:257741 }
[email protected]f598f422012-12-07 08:30:037742 if (!ValidateTextureParameters(function_name, target, format, type, level)) {
7743 return false;
[email protected]81375742012-06-08 00:04:007744 }
[email protected]80eb6b52012-01-19 00:14:417745 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477746 border != 0) {
[email protected]ab09b612013-03-11 22:11:517747 LOCAL_SET_GL_ERROR(
7748 GL_INVALID_VALUE, function_name, "dimensions out of range");
[email protected]f598f422012-12-07 08:30:037749 return false;
[email protected]a93bb842010-02-16 23:03:477750 }
[email protected]81375742012-06-08 00:04:007751 if ((GLES2Util::GetChannelsForFormat(format) &
7752 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && pixels) {
[email protected]ab09b612013-03-11 22:11:517753 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:007754 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037755 function_name, "can not supply data for depth or stencil textures");
7756 return false;
[email protected]81375742012-06-08 00:04:007757 }
[email protected]370eaf12013-05-18 09:19:497758 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7759 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517760 LOCAL_SET_GL_ERROR(
7761 GL_INVALID_OPERATION, function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:037762 return false;
[email protected]a93bb842010-02-16 23:03:477763 }
[email protected]370eaf12013-05-18 09:19:497764 if (texture_ref->texture()->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517765 LOCAL_SET_GL_ERROR(
7766 GL_INVALID_OPERATION, function_name, "texture is immutable");
[email protected]f598f422012-12-07 08:30:037767 return false;
[email protected]97dc7cbe2011-12-06 17:26:177768 }
[email protected]f598f422012-12-07 08:30:037769 return true;
7770}
[email protected]97dc7cbe2011-12-06 17:26:177771
[email protected]f598f422012-12-07 08:30:037772void GLES2DecoderImpl::DoTexImage2D(
7773 GLenum target,
7774 GLint level,
7775 GLenum internal_format,
7776 GLsizei width,
7777 GLsizei height,
7778 GLint border,
7779 GLenum format,
7780 GLenum type,
7781 const void* pixels,
7782 uint32 pixels_size) {
7783 if (!ValidateTexImage2D("glTexImage2D", target, level, internal_format,
7784 width, height, border, format, type, pixels, pixels_size)) {
7785 return;
7786 }
[email protected]7989c9e2013-01-23 06:39:267787
7788 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:517789 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267790 return;
7791 }
7792
[email protected]370eaf12013-05-18 09:19:497793 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7794 Texture* texture = texture_ref->texture();
[email protected]0226c112011-07-22 03:25:077795 GLsizei tex_width = 0;
7796 GLsizei tex_height = 0;
7797 GLenum tex_type = 0;
7798 GLenum tex_format = 0;
7799 bool level_is_same =
[email protected]02965c22013-03-09 02:40:077800 texture->GetLevelSize(target, level, &tex_width, &tex_height) &&
7801 texture->GetLevelType(target, level, &tex_type, &tex_format) &&
[email protected]0226c112011-07-22 03:25:077802 width == tex_width && height == tex_height &&
7803 type == tex_type && format == tex_format;
7804
7805 if (level_is_same && !pixels) {
[email protected]02965c22013-03-09 02:40:077806 // Just set the level texture but mark the texture as uncleared.
[email protected]1bed6222011-12-21 11:21:397807 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497808 texture_ref,
[email protected]1bed6222011-12-21 11:21:397809 target, level, internal_format, width, height, 1, border, format, type,
7810 false);
[email protected]ea72ed222011-08-17 18:58:437811 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:037812 return;
[email protected]0226c112011-07-22 03:25:077813 }
7814
[email protected]02965c22013-03-09 02:40:077815 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427816 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:467817 }
7818
[email protected]1bed6222011-12-21 11:21:397819 if (!teximage2d_faster_than_texsubimage2d_ && level_is_same && pixels) {
[email protected]0226c112011-07-22 03:25:077820 glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels);
[email protected]370eaf12013-05-18 09:19:497821 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]0226c112011-07-22 03:25:077822 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:037823 return;
[email protected]7488d962010-07-16 02:41:587824 }
[email protected]876f6fee2010-08-02 23:10:327825
[email protected]ab09b612013-03-11 22:11:517826 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexImage2D");
[email protected]8f1d2aa2013-05-10 23:45:387827 glTexImage2D(
[email protected]473c01ccb2011-06-07 01:33:307828 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477829 pixels);
[email protected]ab09b612013-03-11 22:11:517830 GLenum error = LOCAL_PEEK_GL_ERROR("glTexImage2D");
[email protected]cadde4a2010-07-31 17:10:437831 if (error == GL_NO_ERROR) {
[email protected]0d6bfdc2011-11-02 01:32:207832 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497833 texture_ref,
[email protected]0d6bfdc2011-11-02 01:32:207834 target, level, internal_format, width, height, 1, border, format, type,
7835 pixels != NULL);
[email protected]b493ee622011-04-13 23:52:007836 tex_image_2d_failed_ = false;
[email protected]cadde4a2010-07-31 17:10:437837 }
[email protected]f598f422012-12-07 08:30:037838 return;
[email protected]b9849abf2009-11-25 19:13:197839}
7840
[email protected]f7a64ee2010-02-01 22:24:147841error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357842 uint32 immediate_data_size, const cmds::TexImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:387843 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
[email protected]b493ee622011-04-13 23:52:007844 tex_image_2d_failed_ = true;
[email protected]b9849abf2009-11-25 19:13:197845 GLenum target = static_cast<GLenum>(c.target);
7846 GLint level = static_cast<GLint>(c.level);
7847 GLint internal_format = static_cast<GLint>(c.internalformat);
7848 GLsizei width = static_cast<GLsizei>(c.width);
7849 GLsizei height = static_cast<GLsizei>(c.height);
7850 GLint border = static_cast<GLint>(c.border);
7851 GLenum format = static_cast<GLenum>(c.format);
7852 GLenum type = static_cast<GLenum>(c.type);
7853 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
7854 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:187855 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347856 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247857 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:347858 NULL)) {
[email protected]a76b0052010-03-05 00:33:187859 return error::kOutOfBounds;
7860 }
[email protected]b9849abf2009-11-25 19:13:197861 const void* pixels = NULL;
7862 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
7863 pixels = GetSharedMemoryAs<const void*>(
7864 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:467865 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147866 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197867 }
7868 }
[email protected]f598f422012-12-07 08:30:037869
7870 DoTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197871 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477872 pixels, pixels_size);
[email protected]f598f422012-12-07 08:30:037873 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197874}
7875
[email protected]f7a64ee2010-02-01 22:24:147876error::Error GLES2DecoderImpl::HandleTexImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357877 uint32 immediate_data_size, const cmds::TexImage2DImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197878 GLenum target = static_cast<GLenum>(c.target);
7879 GLint level = static_cast<GLint>(c.level);
[email protected]ba3176a2009-12-16 18:19:467880 GLint internal_format = static_cast<GLint>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:197881 GLsizei width = static_cast<GLsizei>(c.width);
7882 GLsizei height = static_cast<GLsizei>(c.height);
7883 GLint border = static_cast<GLint>(c.border);
7884 GLenum format = static_cast<GLenum>(c.format);
7885 GLenum type = static_cast<GLenum>(c.type);
[email protected]a76b0052010-03-05 00:33:187886 uint32 size;
[email protected]3458a64a2012-04-10 17:39:347887 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247888 width, height, format, type, state_.unpack_alignment, &size,
7889 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187890 return error::kOutOfBounds;
7891 }
[email protected]07f54fcc2009-12-22 02:46:307892 const void* pixels = GetImmediateDataAs<const void*>(
7893 c, size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467894 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147895 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467896 }
[email protected]a93bb842010-02-16 23:03:477897 DoTexImage2D(
[email protected]ba3176a2009-12-16 18:19:467898 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477899 pixels, size);
[email protected]f7a64ee2010-02-01 22:24:147900 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327901}
7902
[email protected]cadde4a2010-07-31 17:10:437903void GLES2DecoderImpl::DoCompressedTexSubImage2D(
7904 GLenum target,
7905 GLint level,
7906 GLint xoffset,
7907 GLint yoffset,
7908 GLsizei width,
7909 GLsizei height,
7910 GLenum format,
7911 GLsizei image_size,
7912 const void * data) {
[email protected]370eaf12013-05-18 09:19:497913 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7914 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517915 LOCAL_SET_GL_ERROR(
7916 GL_INVALID_OPERATION,
7917 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437918 return;
7919 }
[email protected]370eaf12013-05-18 09:19:497920 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:437921 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:527922 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:077923 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:517924 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:527925 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437926 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:527927 return;
7928 }
7929 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:517930 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:527931 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437932 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:527933 return;
7934 }
[email protected]02965c22013-03-09 02:40:077935 if (!texture->ValidForTexture(
[email protected]df6cf1ad2011-01-29 01:20:527936 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:517937 LOCAL_SET_GL_ERROR(
7938 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437939 return;
7940 }
[email protected]ad84a3a2012-06-08 21:42:437941
7942 if (!ValidateCompressedTexFuncData(
7943 "glCompressedTexSubImage2D", width, height, format, image_size) ||
7944 !ValidateCompressedTexSubDimensions(
7945 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:077946 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:437947 return;
7948 }
7949
7950
[email protected]0d6bfdc2011-11-02 01:32:207951 // Note: There is no need to deal with texture cleared tracking here
7952 // because the validation above means you can only get here if the level
7953 // is already a matching compressed format and in that case
7954 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:437955 glCompressedTexSubImage2D(
7956 target, level, xoffset, yoffset, width, height, format, image_size, data);
7957}
7958
[email protected]6e288612010-12-21 20:45:037959static void Clip(
7960 GLint start, GLint range, GLint sourceRange,
7961 GLint* out_start, GLint* out_range) {
7962 DCHECK(out_start);
7963 DCHECK(out_range);
7964 if (start < 0) {
7965 range += start;
7966 start = 0;
7967 }
7968 GLint end = start + range;
7969 if (end > sourceRange) {
7970 range -= end - sourceRange;
7971 }
7972 *out_start = start;
7973 *out_range = range;
7974}
7975
[email protected]cadde4a2010-07-31 17:10:437976void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:447977 GLenum target,
7978 GLint level,
7979 GLenum internal_format,
7980 GLint x,
7981 GLint y,
7982 GLsizei width,
7983 GLsizei height,
7984 GLint border) {
[email protected]09e17272012-11-30 10:30:447985 DCHECK(!ShouldDeferReads());
[email protected]370eaf12013-05-18 09:19:497986 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7987 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517988 LOCAL_SET_GL_ERROR(
7989 GL_INVALID_OPERATION,
7990 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437991 return;
7992 }
[email protected]370eaf12013-05-18 09:19:497993 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:077994 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517995 LOCAL_SET_GL_ERROR(
7996 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:177997 }
[email protected]80eb6b52012-01-19 00:14:417998 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:187999 border != 0) {
[email protected]ab09b612013-03-11 22:11:518000 LOCAL_SET_GL_ERROR(
8001 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188002 return;
8003 }
[email protected]81375742012-06-08 00:04:008004 if (!ValidateTextureParameters(
8005 "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) {
8006 return;
8007 }
[email protected]f5719fb2010-08-04 18:27:188008
[email protected]9edc6b22010-12-23 02:00:268009 // Check we have compatible formats.
8010 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8011 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8012 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8013
8014 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518015 LOCAL_SET_GL_ERROR(
8016 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268017 return;
8018 }
8019
[email protected]81375742012-06-08 00:04:008020 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518021 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008022 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268023 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8024 return;
8025 }
8026
8027 uint32 estimated_size = 0;
8028 if (!GLES2Util::ComputeImageDataSizes(
8029 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8030 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518031 LOCAL_SET_GL_ERROR(
8032 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268033 return;
8034 }
8035
8036 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518037 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008038 return;
8039 }
8040
[email protected]a0b78dc2011-11-11 10:43:108041 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8042 return;
8043 }
8044
[email protected]ab09b612013-03-11 22:11:518045 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278046 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038047 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268048
[email protected]02965c22013-03-09 02:40:078049 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:428050 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:468051 }
8052
[email protected]9edc6b22010-12-23 02:00:268053 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038054 GLint copyX = 0;
8055 GLint copyY = 0;
8056 GLint copyWidth = 0;
8057 GLint copyHeight = 0;
8058 Clip(x, width, size.width(), &copyX, &copyWidth);
8059 Clip(y, height, size.height(), &copyY, &copyHeight);
8060
8061 if (copyX != x ||
8062 copyY != y ||
8063 copyWidth != width ||
8064 copyHeight != height) {
8065 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208066 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078067 texture->service_id(), texture->target(),
[email protected]4502e6492011-12-14 19:39:158068 target, level, internal_format, GL_UNSIGNED_BYTE, width, height,
[email protected]02965c22013-03-09 02:40:078069 texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518070 LOCAL_SET_GL_ERROR(
8071 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038072 return;
8073 }
[email protected]6e288612010-12-21 20:45:038074 if (copyHeight > 0 && copyWidth > 0) {
8075 GLint dx = copyX - x;
8076 GLint dy = copyY - y;
8077 GLint destX = dx;
8078 GLint destY = dy;
8079 glCopyTexSubImage2D(target, level,
8080 destX, destY, copyX, copyY,
8081 copyWidth, copyHeight);
8082 }
8083 } else {
8084 glCopyTexImage2D(target, level, internal_format,
8085 copyX, copyY, copyWidth, copyHeight, border);
8086 }
[email protected]ab09b612013-03-11 22:11:518087 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438088 if (error == GL_NO_ERROR) {
8089 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498090 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208091 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438092 }
8093}
8094
8095void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448096 GLenum target,
8097 GLint level,
8098 GLint xoffset,
8099 GLint yoffset,
8100 GLint x,
8101 GLint y,
8102 GLsizei width,
8103 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448104 DCHECK(!ShouldDeferReads());
[email protected]370eaf12013-05-18 09:19:498105 TextureRef* texture_ref = GetTextureInfoForTarget(target);
8106 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518107 LOCAL_SET_GL_ERROR(
8108 GL_INVALID_OPERATION,
8109 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438110 return;
8111 }
[email protected]370eaf12013-05-18 09:19:498112 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438113 GLenum type = 0;
8114 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078115 if (!texture->GetLevelType(target, level, &type, &format) ||
8116 !texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438117 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518118 LOCAL_SET_GL_ERROR(
8119 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438120 return;
8121 }
[email protected]02965c22013-03-09 02:40:078122 if (texture->AsyncTransferIsInProgress()) {
[email protected]ab09b612013-03-11 22:11:518123 LOCAL_SET_GL_ERROR(
8124 GL_INVALID_OPERATION,
8125 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598126 return;
8127 }
[email protected]9edc6b22010-12-23 02:00:268128
8129 // Check we have compatible formats.
8130 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8131 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8132 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8133
[email protected]2d3765b2012-10-03 00:31:078134 if (!channels_needed ||
8135 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518136 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438137 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268138 return;
8139 }
8140
[email protected]81375742012-06-08 00:04:008141 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518142 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008143 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438144 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008145 return;
8146 }
8147
[email protected]a0b78dc2011-11-11 10:43:108148 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8149 return;
8150 }
8151
[email protected]de26b3c2011-08-03 21:54:278152 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038153 gfx::Size size = GetBoundReadFrameBufferSize();
8154 GLint copyX = 0;
8155 GLint copyY = 0;
8156 GLint copyWidth = 0;
8157 GLint copyHeight = 0;
8158 Clip(x, width, size.width(), &copyX, &copyWidth);
8159 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208160
[email protected]370eaf12013-05-18 09:19:498161 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:518162 LOCAL_SET_GL_ERROR(
8163 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208164 return;
8165 }
8166
[email protected]6e288612010-12-21 20:45:038167 if (copyX != x ||
8168 copyY != y ||
8169 copyWidth != width ||
8170 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208171 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038172 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348173 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248174 width, height, format, type, state_.unpack_alignment, &pixels_size,
8175 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518176 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438177 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038178 return;
8179 }
[email protected]40d90a22013-04-09 03:39:558180 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038181 memset(zero.get(), 0, pixels_size);
8182 glTexSubImage2D(
8183 target, level, xoffset, yoffset, width, height,
8184 format, type, zero.get());
8185 }
[email protected]0d6bfdc2011-11-02 01:32:208186
[email protected]6e288612010-12-21 20:45:038187 if (copyHeight > 0 && copyWidth > 0) {
8188 GLint dx = copyX - x;
8189 GLint dy = copyY - y;
8190 GLint destX = xoffset + dx;
8191 GLint destY = yoffset + dy;
8192 glCopyTexSubImage2D(target, level,
8193 destX, destY, copyX, copyY,
8194 copyWidth, copyHeight);
8195 }
[email protected]cadde4a2010-07-31 17:10:438196}
8197
[email protected]f598f422012-12-07 08:30:038198bool GLES2DecoderImpl::ValidateTexSubImage2D(
8199 error::Error* error,
8200 const char* function_name,
8201 GLenum target,
8202 GLint level,
8203 GLint xoffset,
8204 GLint yoffset,
8205 GLsizei width,
8206 GLsizei height,
8207 GLenum format,
8208 GLenum type,
8209 const void * data) {
8210 (*error) = error::kNoError;
8211 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518212 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038213 return false;
8214 }
8215 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518216 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038217 return false;
8218 }
8219 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518220 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038221 return false;
8222 }
8223 if (!validators_->texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518224 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]f598f422012-12-07 08:30:038225 return false;
8226 }
8227 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:518228 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]f598f422012-12-07 08:30:038229 return false;
8230 }
[email protected]370eaf12013-05-18 09:19:498231 TextureRef* texture_ref = GetTextureInfoForTarget(target);
8232 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518233 LOCAL_SET_GL_ERROR(
8234 GL_INVALID_OPERATION,
8235 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038236 return false;
[email protected]cadde4a2010-07-31 17:10:438237 }
[email protected]370eaf12013-05-18 09:19:498238 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:528239 GLenum current_type = 0;
8240 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078241 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518242 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038243 GL_INVALID_OPERATION, function_name, "level does not exist.");
8244 return false;
[email protected]df6cf1ad2011-01-29 01:20:528245 }
8246 if (format != internal_format) {
[email protected]ab09b612013-03-11 22:11:518247 LOCAL_SET_GL_ERROR(
8248 GL_INVALID_OPERATION,
8249 function_name, "format does not match internal format.");
[email protected]f598f422012-12-07 08:30:038250 return false;
[email protected]df6cf1ad2011-01-29 01:20:528251 }
8252 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518253 LOCAL_SET_GL_ERROR(
8254 GL_INVALID_OPERATION,
8255 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038256 return false;
[email protected]df6cf1ad2011-01-29 01:20:528257 }
[email protected]02965c22013-03-09 02:40:078258 if (texture->AsyncTransferIsInProgress()) {
[email protected]ab09b612013-03-11 22:11:518259 LOCAL_SET_GL_ERROR(
8260 GL_INVALID_OPERATION,
8261 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598262 return false;
8263 }
[email protected]02965c22013-03-09 02:40:078264 if (!texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438265 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518266 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038267 return false;
[email protected]cadde4a2010-07-31 17:10:438268 }
[email protected]81375742012-06-08 00:04:008269 if ((GLES2Util::GetChannelsForFormat(format) &
8270 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518271 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008272 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038273 function_name, "can not supply data for depth or stencil textures");
8274 return false;
[email protected]81375742012-06-08 00:04:008275 }
[email protected]f598f422012-12-07 08:30:038276 if (data == NULL) {
8277 (*error) = error::kOutOfBounds;
8278 return false;
8279 }
8280 return true;
8281}
[email protected]81375742012-06-08 00:04:008282
[email protected]f598f422012-12-07 08:30:038283error::Error GLES2DecoderImpl::DoTexSubImage2D(
8284 GLenum target,
8285 GLint level,
8286 GLint xoffset,
8287 GLint yoffset,
8288 GLsizei width,
8289 GLsizei height,
8290 GLenum format,
8291 GLenum type,
8292 const void * data) {
8293 error::Error error = error::kNoError;
8294 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8295 xoffset, yoffset, width, height, format, type, data)) {
8296 return error;
8297 }
[email protected]370eaf12013-05-18 09:19:498298 TextureRef* texture_ref = GetTextureInfoForTarget(target);
8299 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:158300 GLsizei tex_width = 0;
8301 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078302 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:158303 DCHECK(ok);
8304 if (xoffset != 0 || yoffset != 0 ||
8305 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:498306 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
8307 target, level)) {
[email protected]ab09b612013-03-11 22:11:518308 LOCAL_SET_GL_ERROR(
8309 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038310 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308311 }
[email protected]63b465922012-09-06 02:04:528312 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158313 glTexSubImage2D(
8314 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038315 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208316 }
[email protected]4502e6492011-12-14 19:39:158317
[email protected]02965c22013-03-09 02:40:078318 if (teximage2d_faster_than_texsubimage2d_ && !texture->IsImmutable()) {
[email protected]63b465922012-09-06 02:04:528319 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158320 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
8321 // same as internal_foramt. If that changes we'll need to look them up.
[email protected]8f1d2aa2013-05-10 23:45:388322 glTexImage2D(
[email protected]4502e6492011-12-14 19:39:158323 target, level, format, width, height, 0, format, type, data);
8324 } else {
[email protected]63b465922012-09-06 02:04:528325 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158326 glTexSubImage2D(
8327 target, level, xoffset, yoffset, width, height, format, type, data);
8328 }
[email protected]370eaf12013-05-18 09:19:498329 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]f598f422012-12-07 08:30:038330 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438331}
8332
[email protected]b493ee622011-04-13 23:52:008333error::Error GLES2DecoderImpl::HandleTexSubImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358334 uint32 immediate_data_size, const cmds::TexSubImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388335 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
[email protected]b493ee622011-04-13 23:52:008336 GLboolean internal = static_cast<GLboolean>(c.internal);
8337 if (internal == GL_TRUE && tex_image_2d_failed_)
8338 return error::kNoError;
8339
8340 GLenum target = static_cast<GLenum>(c.target);
8341 GLint level = static_cast<GLint>(c.level);
8342 GLint xoffset = static_cast<GLint>(c.xoffset);
8343 GLint yoffset = static_cast<GLint>(c.yoffset);
8344 GLsizei width = static_cast<GLsizei>(c.width);
8345 GLsizei height = static_cast<GLsizei>(c.height);
8346 GLenum format = static_cast<GLenum>(c.format);
8347 GLenum type = static_cast<GLenum>(c.type);
8348 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348349 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248350 width, height, format, type, state_.unpack_alignment, &data_size,
8351 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008352 return error::kOutOfBounds;
8353 }
8354 const void* pixels = GetSharedMemoryAs<const void*>(
8355 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038356 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008357 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008358}
8359
8360error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:358361 uint32 immediate_data_size, const cmds::TexSubImage2DImmediate& c) {
[email protected]b493ee622011-04-13 23:52:008362 GLboolean internal = static_cast<GLboolean>(c.internal);
8363 if (internal == GL_TRUE && tex_image_2d_failed_)
8364 return error::kNoError;
8365
8366 GLenum target = static_cast<GLenum>(c.target);
8367 GLint level = static_cast<GLint>(c.level);
8368 GLint xoffset = static_cast<GLint>(c.xoffset);
8369 GLint yoffset = static_cast<GLint>(c.yoffset);
8370 GLsizei width = static_cast<GLsizei>(c.width);
8371 GLsizei height = static_cast<GLsizei>(c.height);
8372 GLenum format = static_cast<GLenum>(c.format);
8373 GLenum type = static_cast<GLenum>(c.type);
8374 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348375 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248376 width, height, format, type, state_.unpack_alignment, &data_size,
8377 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008378 return error::kOutOfBounds;
8379 }
8380 const void* pixels = GetImmediateDataAs<const void*>(
8381 c, data_size, immediate_data_size);
[email protected]f598f422012-12-07 08:30:038382 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008383 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008384}
8385
[email protected]f7a64ee2010-02-01 22:24:148386error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]ed9f9cd2013-02-27 21:12:358387 uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:368388 GLuint index = static_cast<GLuint>(c.index);
8389 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:358390 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:258391 Result* result = GetSharedMemoryAs<Result*>(
8392 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:368393 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:148394 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:368395 }
[email protected]07d0cc82010-02-17 04:51:408396 // Check that the client initialized the result.
8397 if (result->size != 0) {
8398 return error::kInvalidArguments;
8399 }
[email protected]9438b012010-06-15 22:55:058400 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:518401 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8402 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:148403 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368404 }
[email protected]3916c97e2010-02-25 03:20:508405 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:518406 LOCAL_SET_GL_ERROR(
8407 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:148408 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368409 }
[email protected]0bfd9882010-02-05 23:02:258410 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:088411 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:358412 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:148413 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328414}
8415
[email protected]f7b85372010-02-03 01:11:378416bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:428417 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:378418 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:128419 error::Error* error, GLint* real_location,
8420 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:108421 DCHECK(error);
8422 DCHECK(service_id);
8423 DCHECK(result_pointer);
8424 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:128425 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:378426 *error = error::kNoError;
8427 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:258428 SizedResult<GLint>* result;
8429 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8430 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8431 if (!result) {
[email protected]f7b85372010-02-03 01:11:378432 *error = error::kOutOfBounds;
8433 return false;
8434 }
[email protected]0bfd9882010-02-05 23:02:258435 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:378436 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:258437 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:428438 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
8439 if (!program) {
[email protected]ae51d192010-04-27 00:48:038440 return false;
8441 }
[email protected]df37b9932013-03-08 05:21:428442 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:378443 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:518444 LOCAL_SET_GL_ERROR(
8445 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:378446 return false;
8447 }
[email protected]df37b9932013-03-08 05:21:428448 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:368449 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:358450 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428451 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:128452 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:368453 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:378454 // No such location.
[email protected]ab09b612013-03-11 22:11:518455 LOCAL_SET_GL_ERROR(
8456 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:378457 return false;
8458 }
[email protected]43c2f1f2011-03-25 18:35:368459 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:508460 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:378461 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:518462 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:378463 return false;
8464 }
[email protected]0bfd9882010-02-05 23:02:258465 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8466 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8467 if (!result) {
[email protected]f7b85372010-02-03 01:11:378468 *error = error::kOutOfBounds;
8469 return false;
8470 }
[email protected]0bfd9882010-02-05 23:02:258471 result->size = size;
[email protected]939e7362010-05-13 20:49:108472 *result_type = type;
[email protected]f7b85372010-02-03 01:11:378473 return true;
8474}
8475
[email protected]f7a64ee2010-02-01 22:24:148476error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]ed9f9cd2013-02-27 21:12:358477 uint32 immediate_data_size, const cmds::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:378478 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338479 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378480 GLuint service_id;
[email protected]939e7362010-05-13 20:49:108481 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:128482 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378483 Error error;
[email protected]0bfd9882010-02-05 23:02:258484 void* result;
[email protected]f7b85372010-02-03 01:11:378485 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128486 program, fake_location, c.params_shm_id, c.params_shm_offset,
8487 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:258488 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:128489 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:358490 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:378491 }
8492 return error;
[email protected]96449d2c2009-11-25 00:01:328493}
8494
[email protected]f7a64ee2010-02-01 22:24:148495error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]ed9f9cd2013-02-27 21:12:358496 uint32 immediate_data_size, const cmds::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:378497 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338498 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378499 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:128500 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378501 Error error;
[email protected]ed9f9cd2013-02-27 21:12:358502 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:108503 Result* result;
8504 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:378505 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128506 program, fake_location, c.params_shm_id, c.params_shm_offset,
8507 &error, &real_location, &service_id,
8508 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:108509 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8510 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8511 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:558512 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:128513 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:108514 GLfloat* dst = result->GetData();
8515 for (GLsizei ii = 0; ii < num_values; ++ii) {
8516 dst[ii] = (temp[ii] != 0);
8517 }
8518 } else {
[email protected]1b0a6752012-02-22 03:44:128519 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:108520 }
[email protected]f7b85372010-02-03 01:11:378521 }
8522 return error;
[email protected]96449d2c2009-11-25 00:01:328523}
8524
[email protected]f7a64ee2010-02-01 22:24:148525error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]ed9f9cd2013-02-27 21:12:358526 uint32 immediate_data_size, const cmds::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:258527 GLenum shader_type = static_cast<GLenum>(c.shadertype);
8528 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:358529 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:258530 Result* result = GetSharedMemoryAs<Result*>(
8531 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8532 if (!result) {
8533 return error::kOutOfBounds;
8534 }
[email protected]07d0cc82010-02-17 04:51:408535 // Check that the client initialized the result.
8536 if (result->success != 0) {
8537 return error::kInvalidArguments;
8538 }
[email protected]9438b012010-06-15 22:55:058539 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:518540 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538541 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:298542 return error::kNoError;
8543 }
[email protected]9438b012010-06-15 22:55:058544 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:518545 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538546 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:298547 return error::kNoError;
8548 }
8549
8550 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:408551
8552 GLint range[2] = {0, 0};
8553 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:218554 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:408555
8556 result->min_range = range[0];
8557 result->max_range = range[1];
8558 result->precision = precision;
8559
[email protected]f7a64ee2010-02-01 22:24:148560 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328561}
8562
[email protected]f7a64ee2010-02-01 22:24:148563error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]ed9f9cd2013-02-27 21:12:358564 uint32 immediate_data_size, const cmds::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:258565 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:428566 GLuint program_id = static_cast<GLuint>(c.program);
8567 Program* program = GetProgramInfoNotShader(
8568 program_id, "glGetAttachedShaders");
8569 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258570 return error::kNoError;
8571 }
[email protected]ed9f9cd2013-02-27 21:12:358572 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:258573 uint32 max_count = Result::ComputeMaxResults(result_size);
8574 Result* result = GetSharedMemoryAs<Result*>(
8575 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8576 if (!result) {
8577 return error::kOutOfBounds;
8578 }
[email protected]07d0cc82010-02-17 04:51:408579 // Check that the client initialized the result.
8580 if (result->size != 0) {
8581 return error::kInvalidArguments;
8582 }
[email protected]0bfd9882010-02-05 23:02:258583 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:038584 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:428585 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:258586 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:038587 if (!shader_manager()->GetClientId(result->GetData()[ii],
8588 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:258589 NOTREACHED();
8590 return error::kGenericError;
8591 }
8592 }
8593 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:148594 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328595}
8596
[email protected]f7a64ee2010-02-01 22:24:148597error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]ed9f9cd2013-02-27 21:12:358598 uint32 immediate_data_size, const cmds::GetActiveUniform& c) {
[email protected]df37b9932013-03-08 05:21:428599 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258600 GLuint index = c.index;
8601 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358602 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:258603 Result* result = GetSharedMemoryAs<Result*>(
8604 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8605 if (!result) {
8606 return error::kOutOfBounds;
8607 }
[email protected]07d0cc82010-02-17 04:51:408608 // Check that the client initialized the result.
8609 if (result->success != 0) {
8610 return error::kInvalidArguments;
8611 }
[email protected]df37b9932013-03-08 05:21:428612 Program* program = GetProgramInfoNotShader(
8613 program_id, "glGetActiveUniform");
8614 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258615 return error::kNoError;
8616 }
[email protected]ed9f9cd2013-02-27 21:12:358617 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428618 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:258619 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:518620 LOCAL_SET_GL_ERROR(
8621 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258622 return error::kNoError;
8623 }
8624 result->success = 1; // true.
8625 result->size = uniform_info->size;
8626 result->type = uniform_info->type;
8627 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298628 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148629 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328630}
8631
[email protected]f7a64ee2010-02-01 22:24:148632error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]ed9f9cd2013-02-27 21:12:358633 uint32 immediate_data_size, const cmds::GetActiveAttrib& c) {
[email protected]df37b9932013-03-08 05:21:428634 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258635 GLuint index = c.index;
8636 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358637 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:258638 Result* result = GetSharedMemoryAs<Result*>(
8639 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8640 if (!result) {
8641 return error::kOutOfBounds;
8642 }
[email protected]07d0cc82010-02-17 04:51:408643 // Check that the client initialized the result.
8644 if (result->success != 0) {
8645 return error::kInvalidArguments;
8646 }
[email protected]df37b9932013-03-08 05:21:428647 Program* program = GetProgramInfoNotShader(
8648 program_id, "glGetActiveAttrib");
8649 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258650 return error::kNoError;
8651 }
[email protected]ed9f9cd2013-02-27 21:12:358652 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:428653 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:258654 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:518655 LOCAL_SET_GL_ERROR(
8656 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258657 return error::kNoError;
8658 }
8659 result->success = 1; // true.
8660 result->size = attrib_info->size;
8661 result->type = attrib_info->type;
8662 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298663 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148664 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328665}
8666
[email protected]b273e432010-04-12 17:23:588667error::Error GLES2DecoderImpl::HandleShaderBinary(
[email protected]ed9f9cd2013-02-27 21:12:358668 uint32 immediate_data_size, const cmds::ShaderBinary& c) {
[email protected]b273e432010-04-12 17:23:588669#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:518670 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:588671 return error::kNoError;
8672#else
8673 GLsizei n = static_cast<GLsizei>(c.n);
8674 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:518675 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:588676 return error::kNoError;
8677 }
8678 GLsizei length = static_cast<GLsizei>(c.length);
8679 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:518680 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:588681 return error::kNoError;
8682 }
8683 uint32 data_size;
8684 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
8685 return error::kOutOfBounds;
8686 }
8687 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
8688 c.shaders_shm_id, c.shaders_shm_offset, data_size);
8689 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
8690 const void* binary = GetSharedMemoryAs<const void*>(
8691 c.binary_shm_id, c.binary_shm_offset, length);
8692 if (shaders == NULL || binary == NULL) {
8693 return error::kOutOfBounds;
8694 }
8695 scoped_array<GLuint> service_ids(new GLuint[n]);
8696 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:428697 Shader* shader = GetShader(shaders[ii]);
8698 if (!shader) {
[email protected]ab09b612013-03-11 22:11:518699 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:588700 return error::kNoError;
8701 }
[email protected]df37b9932013-03-08 05:21:428702 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:588703 }
8704 // TODO(gman): call glShaderBinary
8705 return error::kNoError;
8706#endif
8707}
8708
[email protected]6d792ee12013-05-15 00:40:568709void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:498710 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:088711
[email protected]64ace852011-05-19 21:49:498712 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:428713 // TRACE_EVENT for gpu tests:
8714 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:428715 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:428716 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
8717 "width", (is_offscreen ? offscreen_size_.width() :
8718 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:568719 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:498720 "offscreen", is_offscreen,
8721 "frame", this_frame_number);
[email protected]6217d392010-03-25 22:08:358722 // If offscreen then don't actually SwapBuffers to the display. Just copy
8723 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:498724 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:318725 TRACE_EVENT2("gpu", "Offscreen",
8726 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:538727 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
8728 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
8729 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
8730 // fix this.
[email protected]62e155e2012-10-23 22:43:158731 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:538732 offscreen_saved_frame_buffer_->Create();
8733 glFinish();
8734 }
8735
8736 // Allocate the offscreen saved color texture.
8737 DCHECK(offscreen_saved_color_format_);
8738 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:098739 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:538740
8741 offscreen_saved_frame_buffer_->AttachRenderTexture(
8742 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:058743 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
8744 if (offscreen_saved_frame_buffer_->CheckStatus() !=
8745 GL_FRAMEBUFFER_COMPLETE) {
8746 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
8747 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:568748 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
8749 return;
[email protected]f0cfe752013-01-14 01:09:058750 }
[email protected]1fb8c482011-08-31 01:01:538751
[email protected]f0cfe752013-01-14 01:09:058752 // Clear the offscreen color texture.
8753 // TODO(piman): Is this still necessary?
8754 {
8755 ScopedFrameBufferBinder binder(this,
8756 offscreen_saved_frame_buffer_->id());
8757 glClearColor(0, 0, 0, 0);
8758 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
8759 glDisable(GL_SCISSOR_TEST);
8760 glClear(GL_COLOR_BUFFER_BIT);
8761 RestoreClearState();
8762 }
[email protected]1fb8c482011-08-31 01:01:538763 }
8764
8765 UpdateParentTextureInfo();
8766 }
8767
[email protected]f0cfe752013-01-14 01:09:058768 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:568769 return;
[email protected]ab09b612013-03-11 22:11:518770 ScopedGLErrorSuppressor suppressor(
[email protected]6d792ee12013-05-15 00:40:568771 "GLES2DecoderImpl::DoSwapBuffers", this);
[email protected]6217d392010-03-25 22:08:358772
[email protected]34ff8b0c2010-10-01 20:06:028773 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:138774 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:278775 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:488776 } else {
[email protected]069944672012-04-25 20:52:238777 ScopedFrameBufferBinder binder(this,
8778 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:138779
[email protected]069944672012-04-25 20:52:238780 if (offscreen_target_buffer_preserved_) {
8781 // Copy the target frame buffer to the saved offscreen texture.
8782 offscreen_saved_color_texture_->Copy(
8783 offscreen_saved_color_texture_->size(),
8784 offscreen_saved_color_format_);
8785 } else {
8786 // Flip the textures in the parent context via the texture manager.
8787 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:498788 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:238789 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:568790
[email protected]069944672012-04-25 20:52:238791 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
8792 offscreen_target_frame_buffer_->AttachRenderTexture(
8793 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:488794 }
[email protected]069944672012-04-25 20:52:238795
8796 // Ensure the side effects of the copy are visible to the parent
8797 // context. There is no need to do this for ANGLE because it uses a
8798 // single D3D device for all contexts.
8799 if (!IsAngle())
8800 glFlush();
[email protected]0c8c9d22010-06-25 17:36:398801 }
[email protected]6217d392010-03-25 22:08:358802 } else {
[email protected]111975c62012-09-06 01:37:318803 TRACE_EVENT2("gpu", "Onscreen",
8804 "width", surface_->GetSize().width(),
8805 "height", surface_->GetSize().height());
[email protected]f62a5ab2011-05-23 20:34:158806 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:018807 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:568808 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:018809 }
[email protected]6217d392010-03-25 22:08:358810 }
[email protected]6217d392010-03-25 22:08:358811}
8812
[email protected]d4239852011-08-12 04:51:228813error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358814 uint32 immediate_data_size, const cmds::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:188815 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288816 if (!bucket || bucket->size() == 0) {
8817 return error::kInvalidArguments;
8818 }
[email protected]ed9f9cd2013-02-27 21:12:358819 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:188820 Result* result = GetSharedMemoryAs<Result*>(
8821 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8822 if (!result) {
8823 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:108824 }
[email protected]b1d2dcb2010-05-17 19:24:188825 // Check that the client initialized the result.
8826 if (*result != 0) {
8827 return error::kInvalidArguments;
8828 }
8829 std::string feature_str;
8830 if (!bucket->GetAsString(&feature_str)) {
8831 return error::kInvalidArguments;
8832 }
8833
8834 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:228835 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:188836 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:228837 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:408838 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
8839 // TODO(gman): decide how to remove the need for this const_cast.
8840 // I could make validators_ non const but that seems bad as this is the only
8841 // place it is needed. I could make some special friend class of validators
8842 // just to allow this to set them. That seems silly. I could refactor this
8843 // code to use the extension mechanism or the initialization attributes to
8844 // turn this feature on. Given that the only real point of this is to make
8845 // the conformance tests pass and given that there is lots of real work that
8846 // needs to be done it seems like refactoring for one to one of those
8847 // methods is a very low priority.
8848 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:048849 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
8850 force_webgl_glsl_validation_ = true;
8851 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:188852 } else {
8853 return error::kNoError;
8854 }
8855
8856 *result = 1; // true.
8857 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:108858}
8859
[email protected]c2f8c8402010-12-06 18:07:248860error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
8861 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:358862 const cmds::GetRequestableExtensionsCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:248863 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:358864 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]e82fb792011-09-22 00:33:298865 info->Initialize(disallowed_features_, NULL);
[email protected]c2f8c8402010-12-06 18:07:248866 bucket->SetFromString(info->extensions().c_str());
8867 return error::kNoError;
8868}
8869
8870error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358871 uint32 immediate_data_size, const cmds::RequestExtensionCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:248872 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288873 if (!bucket || bucket->size() == 0) {
8874 return error::kInvalidArguments;
8875 }
[email protected]c2f8c8402010-12-06 18:07:248876 std::string feature_str;
8877 if (!bucket->GetAsString(&feature_str)) {
8878 return error::kInvalidArguments;
8879 }
8880
[email protected]4b7eba92013-01-08 02:23:568881 bool desire_webgl_glsl_validation =
8882 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
8883 bool desire_standard_derivatives = false;
8884 if (force_webgl_glsl_validation_) {
8885 desire_standard_derivatives =
8886 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:048887 }
8888
[email protected]4b7eba92013-01-08 02:23:568889 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
8890 desire_standard_derivatives != derivatives_explicitly_enabled_) {
8891 force_webgl_glsl_validation_ = desire_webgl_glsl_validation;
8892 derivatives_explicitly_enabled_ = desire_standard_derivatives;
[email protected]c2f8c8402010-12-06 18:07:248893 InitializeShaderTranslator();
8894 }
8895
[email protected]302ce6d2011-07-07 23:28:118896 UpdateCapabilities();
8897
[email protected]c2f8c8402010-12-06 18:07:248898 return error::kNoError;
8899}
8900
[email protected]372e0412011-06-28 16:08:568901error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358902 uint32 immediate_data_size, const cmds::GetMultipleIntegervCHROMIUM& c) {
[email protected]372e0412011-06-28 16:08:568903 GLuint count = c.count;
8904 uint32 pnames_size;
8905 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
8906 return error::kOutOfBounds;
8907 }
8908 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
8909 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
8910 if (pnames == NULL) {
8911 return error::kOutOfBounds;
8912 }
8913
8914 // We have to copy them since we use them twice so the client
8915 // can't change them between the time we validate them and the time we use
8916 // them.
[email protected]40d90a22013-04-09 03:39:558917 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:568918 memcpy(enums.get(), pnames, pnames_size);
8919
8920 // Count up the space needed for the result.
8921 uint32 num_results = 0;
8922 for (GLuint ii = 0; ii < count; ++ii) {
8923 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
8924 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:518925 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8926 "glGetMulitpleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:568927 return error::kNoError;
8928 }
8929 // Num will never be more than 4.
8930 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:478931 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:568932 return error::kOutOfBounds;
8933 }
8934 }
8935
8936 uint32 result_size = 0;
8937 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
8938 return error::kOutOfBounds;
8939 }
8940
8941 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:518942 LOCAL_SET_GL_ERROR(
8943 GL_INVALID_VALUE,
8944 "glGetMulitpleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:568945 return error::kNoError;
8946 }
8947
8948 GLint* results = GetSharedMemoryAs<GLint*>(
8949 c.results_shm_id, c.results_shm_offset, result_size);
8950 if (results == NULL) {
8951 return error::kOutOfBounds;
8952 }
8953
8954 // Check the results have been cleared in case the context was lost.
8955 for (uint32 ii = 0; ii < num_results; ++ii) {
8956 if (results[ii]) {
8957 return error::kInvalidArguments;
8958 }
8959 }
8960
8961 // Get each result.
8962 GLint* start = results;
8963 for (GLuint ii = 0; ii < count; ++ii) {
8964 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:268965 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:538966 !GetHelper(enums[ii], results, &num_written)) {
[email protected]b0ce0982013-05-13 18:51:488967 DoGetIntegerv(enums[ii], results);
[email protected]372e0412011-06-28 16:08:568968 }
8969 results += num_written;
8970 }
8971
8972 // Just to verify. Should this be a DCHECK?
8973 if (static_cast<uint32>(results - start) != num_results) {
8974 return error::kOutOfBounds;
8975 }
8976
8977 return error::kNoError;
8978}
8979
[email protected]2318d342011-07-11 22:27:428980error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358981 uint32 immediate_data_size, const cmds::GetProgramInfoCHROMIUM& c) {
[email protected]df37b9932013-03-08 05:21:428982 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:428983 uint32 bucket_id = c.bucket_id;
8984 Bucket* bucket = CreateBucket(bucket_id);
8985 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:428986 Program* program = NULL;
8987 program = GetProgram(program_id);
8988 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:468989 return error::kNoError;
[email protected]2318d342011-07-11 22:27:428990 }
[email protected]df37b9932013-03-08 05:21:428991 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:428992 return error::kNoError;
8993}
8994
[email protected]38d139d2011-07-14 00:38:438995error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
8996 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:438997 case GL_NO_ERROR:
8998 // TODO(kbr): improve the precision of the error code in this case.
8999 // Consider delegating to context for error code if MakeCurrent fails.
9000 return error::kUnknown;
9001 case GL_GUILTY_CONTEXT_RESET_ARB:
9002 return error::kGuilty;
9003 case GL_INNOCENT_CONTEXT_RESET_ARB:
9004 return error::kInnocent;
9005 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9006 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439007 }
9008
9009 NOTREACHED();
9010 return error::kUnknown;
9011}
9012
9013bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099014 if (reset_status_ != GL_NO_ERROR) {
9015 return true;
9016 }
[email protected]706b69f2012-07-27 04:59:309017 if (context_->WasAllocatedUsingRobustnessExtension()) {
9018 GLenum status = GL_NO_ERROR;
9019 if (has_robustness_extension_)
9020 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439021 if (status != GL_NO_ERROR) {
9022 // The graphics card was reset. Signal a lost context to the application.
9023 reset_status_ = status;
9024 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099025 << " context lost via ARB/EXT_robustness. Reset status = "
9026 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:439027 return true;
9028 }
9029 }
9030 return false;
9031}
9032
[email protected]c4485aad62012-12-17 10:19:099033void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9034 // Only loses the context once.
9035 if (reset_status_ != GL_NO_ERROR) {
9036 return;
9037 }
9038
9039 // Marks this context as lost.
9040 reset_status_ = reset_status;
9041 current_decoder_error_ = error::kLostContext;
9042
9043 // Loses the parent's context.
9044 if (parent_) {
9045 parent_->LoseContext(reset_status);
9046 }
9047
9048 // Loses any child contexts.
9049 for (ChildList::iterator it = children_.begin();
9050 it != children_.end();
9051 ++it) {
9052 (*it)->LoseContext(reset_status);
9053 }
9054}
9055
9056error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359057 uint32 immediate_data_size, const cmds::LoseContextCHROMIUM& c) {
[email protected]c4485aad62012-12-17 10:19:099058 GLenum current = static_cast<GLenum>(c.current);
9059 GLenum other = static_cast<GLenum>(c.other);
9060 if (!validators_->reset_status.IsValid(current)) {
[email protected]ab09b612013-03-11 22:11:519061 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9062 "glLoseContextCHROMIUM", current, "current");
[email protected]c4485aad62012-12-17 10:19:099063 }
9064 if (!validators_->reset_status.IsValid(other)) {
[email protected]ab09b612013-03-11 22:11:519065 LOCAL_SET_GL_ERROR_INVALID_ENUM("glLoseContextCHROMIUM", other, "other");
[email protected]c4485aad62012-12-17 10:19:099066 }
9067 group_->LoseContexts(other);
9068 reset_status_ = current;
9069 current_decoder_error_ = error::kLostContext;
9070 return error::kLostContext;
9071}
9072
[email protected]b096d032013-03-08 03:08:019073error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
9074 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) {
9075 return error::kUnknownCommand;
9076}
9077
[email protected]840a7e462013-02-27 01:29:519078error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359079 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) {
[email protected]840a7e462013-02-27 01:29:519080 if (wait_sync_point_callback_.is_null())
9081 return error::kNoError;
9082
9083 return wait_sync_point_callback_.Run(c.sync_point) ?
9084 error::kNoError : error::kDeferCommandUntilLater;
9085}
9086
[email protected]882ba1e22012-03-08 19:02:539087bool GLES2DecoderImpl::GenQueriesEXTHelper(
9088 GLsizei n, const GLuint* client_ids) {
9089 for (GLsizei ii = 0; ii < n; ++ii) {
9090 if (query_manager_->GetQuery(client_ids[ii])) {
9091 return false;
9092 }
9093 }
[email protected]c45f1972012-03-14 07:27:369094 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
[email protected]882ba1e22012-03-08 19:02:539095 return true;
9096}
9097
9098void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9099 GLsizei n, const GLuint* client_ids) {
9100 for (GLsizei ii = 0; ii < n; ++ii) {
9101 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9102 if (query && !query->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:249103 if (query == state_.current_query) {
9104 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539105 }
[email protected]c45f1972012-03-14 07:27:369106 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539107 query_manager_->RemoveQuery(client_ids[ii]);
9108 }
9109 }
9110}
9111
[email protected]22e3f552012-03-13 01:54:199112bool GLES2DecoderImpl::ProcessPendingQueries() {
9113 if (query_manager_.get() == NULL) {
9114 return false;
9115 }
[email protected]c45f1972012-03-14 07:27:369116 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:199117 current_decoder_error_ = error::kOutOfBounds;
9118 }
9119 return query_manager_->HavePendingQueries();
9120}
9121
[email protected]2b1767cf2013-03-16 09:25:059122bool GLES2DecoderImpl::HasMoreIdleWork() {
9123 return async_pixel_transfer_delegate_->NeedsProcessMorePendingTransfers();
9124}
9125
9126void GLES2DecoderImpl::PerformIdleWork() {
9127 if (!async_pixel_transfer_delegate_->NeedsProcessMorePendingTransfers())
9128 return;
[email protected]b75ff642013-05-09 05:30:299129 async_pixel_transfer_delegate_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059130 ProcessFinishedAsyncTransfers();
9131}
9132
[email protected]882ba1e22012-03-08 19:02:539133error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359134 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539135 GLenum target = static_cast<GLenum>(c.target);
9136 GLuint client_id = static_cast<GLuint>(c.id);
9137 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9138 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9139
[email protected]c45f1972012-03-14 07:27:369140 switch (target) {
9141 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559142 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]0713f43d2012-12-14 22:41:309143 case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009144 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369145 break;
9146 default:
[email protected]62e155e2012-10-23 22:43:159147 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519148 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009149 GL_INVALID_OPERATION, "glBeginQueryEXT",
9150 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369151 return error::kNoError;
9152 }
9153 break;
[email protected]882ba1e22012-03-08 19:02:539154 }
9155
[email protected]e259eb412012-10-13 05:47:249156 if (state_.current_query) {
[email protected]ab09b612013-03-11 22:11:519157 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439158 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539159 return error::kNoError;
9160 }
9161
9162 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519163 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539164 return error::kNoError;
9165 }
9166
9167 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9168 if (!query) {
[email protected]c45f1972012-03-14 07:27:369169 // TODO(gman): Decide if we need this check.
9170 //
[email protected]882ba1e22012-03-08 19:02:539171 // Checks id was made by glGenQueries
[email protected]c45f1972012-03-14 07:27:369172 //
9173 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
9174 // for all Query ids but from the POV of the command buffer service maybe
9175 // you don't.
9176 //
9177 // The client can enforce this. I don't think the service cares.
9178 //
9179 // IdAllocatorInterface* id_allocator =
9180 // group_->GetIdAllocator(id_namespaces::kQueries);
9181 // if (!id_allocator->InUse(client_id)) {
[email protected]ab09b612013-03-11 22:11:519182 // LOCAL_SET_GL_ERROR(
9183 // GL_INVALID_OPERATION,
9184 // "glBeginQueryEXT", "id not made by glGenQueriesEXT");
[email protected]c45f1972012-03-14 07:27:369185 // return error::kNoError;
9186 // }
9187 query = query_manager_->CreateQuery(
9188 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539189 }
9190
[email protected]c45f1972012-03-14 07:27:369191 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519192 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439193 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539194 return error::kNoError;
9195 } else if (query->shm_id() != sync_shm_id ||
9196 query->shm_offset() != sync_shm_offset) {
9197 DLOG(ERROR) << "Shared memory used by query not the same as before";
9198 return error::kInvalidArguments;
9199 }
9200
[email protected]c45f1972012-03-14 07:27:369201 if (!query_manager_->BeginQuery(query)) {
9202 return error::kOutOfBounds;
9203 }
[email protected]882ba1e22012-03-08 19:02:539204
[email protected]e259eb412012-10-13 05:47:249205 state_.current_query = query;
[email protected]882ba1e22012-03-08 19:02:539206 return error::kNoError;
9207}
9208
9209error::Error GLES2DecoderImpl::HandleEndQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359210 uint32 immediate_data_size, const cmds::EndQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539211 GLenum target = static_cast<GLenum>(c.target);
9212 uint32 submit_count = static_cast<GLuint>(c.submit_count);
9213
[email protected]e259eb412012-10-13 05:47:249214 if (!state_.current_query) {
[email protected]ab09b612013-03-11 22:11:519215 LOCAL_SET_GL_ERROR(
9216 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539217 return error::kNoError;
9218 }
[email protected]e259eb412012-10-13 05:47:249219 if (state_.current_query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519220 LOCAL_SET_GL_ERROR(
9221 GL_INVALID_OPERATION,
9222 "glEndQueryEXT", "target does not match active query");
[email protected]882ba1e22012-03-08 19:02:539223 return error::kNoError;
9224 }
[email protected]882ba1e22012-03-08 19:02:539225
[email protected]e259eb412012-10-13 05:47:249226 if (!query_manager_->EndQuery(state_.current_query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:369227 return error::kOutOfBounds;
9228 }
9229
[email protected]fe8d73c2013-02-16 22:37:329230 query_manager_->ProcessPendingTransferQueries();
9231
[email protected]e259eb412012-10-13 05:47:249232 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539233 return error::kNoError;
9234}
9235
[email protected]944b62f32012-09-27 02:20:469236bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9237 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469238 for (GLsizei ii = 0; ii < n; ++ii) {
9239 if (GetVertexAttribManager(client_ids[ii])) {
9240 return false;
9241 }
9242 }
[email protected]ab4fd7282012-10-12 16:25:579243
[email protected]62e155e2012-10-23 22:43:159244 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579245 // Emulated VAO
9246 for (GLsizei ii = 0; ii < n; ++ii) {
9247 CreateVertexAttribManager(client_ids[ii], 0);
9248 }
9249 } else {
[email protected]40d90a22013-04-09 03:39:559250 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:579251
9252 glGenVertexArraysOES(n, service_ids.get());
9253 for (GLsizei ii = 0; ii < n; ++ii) {
9254 CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
9255 }
[email protected]944b62f32012-09-27 02:20:469256 }
[email protected]ab4fd7282012-10-12 16:25:579257
[email protected]944b62f32012-09-27 02:20:469258 return true;
9259}
9260
9261void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9262 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469263 for (GLsizei ii = 0; ii < n; ++ii) {
9264 VertexAttribManager* vao =
9265 GetVertexAttribManager(client_ids[ii]);
9266 if (vao && !vao->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:249267 if (state_.vertex_attrib_manager == vao) {
9268 state_.vertex_attrib_manager = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469269 }
9270 RemoveVertexAttribManager(client_ids[ii]);
9271 }
9272 }
9273}
9274
9275void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469276 VertexAttribManager* vao = NULL;
9277 GLuint service_id = 0;
9278 if (client_id != 0) {
9279 vao = GetVertexAttribManager(client_id);
9280 if (!vao) {
9281 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9282 // only allows names that have been previously generated. As such, we do
9283 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:519284 LOCAL_SET_GL_ERROR(
9285 GL_INVALID_OPERATION,
9286 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:469287 current_decoder_error_ = error::kNoError;
9288 return;
9289 } else {
9290 service_id = vao->service_id();
9291 }
[email protected]944b62f32012-09-27 02:20:469292 } else {
[email protected]ab4fd7282012-10-12 16:25:579293 vao = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469294 }
9295
[email protected]ab4fd7282012-10-12 16:25:579296 // Only set the VAO state if it's changed
[email protected]e259eb412012-10-13 05:47:249297 if (state_.vertex_attrib_manager != vao) {
9298 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:159299 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579300 EmulateVertexArrayState();
9301 } else {
9302 glBindVertexArrayOES(service_id);
9303 }
9304 }
9305}
9306
9307// Used when OES_vertex_array_object isn't natively supported
9308void GLES2DecoderImpl::EmulateVertexArrayState() {
9309 // Setup the Vertex attribute state
9310 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
9311 RestoreStateForAttrib(vv);
9312 }
9313
9314 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:219315 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:249316 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:579317 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9318 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:469319}
9320
9321bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469322 const VertexAttribManager* vao =
9323 GetVertexAttribManager(client_id);
9324 return vao && vao->IsValid() && !vao->IsDeleted();
9325}
9326
[email protected]b0af4f52011-09-28 22:04:429327error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM(
9328 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359329 const cmds::CreateStreamTextureCHROMIUM& c) {
[email protected]62e155e2012-10-23 22:43:159330 if (!features().chromium_stream_texture) {
[email protected]ab09b612013-03-11 22:11:519331 LOCAL_SET_GL_ERROR(
9332 GL_INVALID_OPERATION,
9333 "glOpenStreamTextureCHROMIUM", "not supported.");
[email protected]b0af4f52011-09-28 22:04:429334 return error::kNoError;
9335 }
9336
9337 uint32 client_id = c.client_id;
[email protected]ed9f9cd2013-02-27 21:12:359338 typedef cmds::CreateStreamTextureCHROMIUM::Result Result;
[email protected]b0af4f52011-09-28 22:04:429339 Result* result = GetSharedMemoryAs<Result*>(
9340 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9341
[email protected]e5081262012-01-05 23:09:039342 if (!result)
9343 return error::kOutOfBounds;
[email protected]b0af4f52011-09-28 22:04:429344 *result = GL_ZERO;
[email protected]370eaf12013-05-18 09:19:499345 TextureRef* texture_ref = texture_manager()->GetTexture(client_id);
9346 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519347 LOCAL_SET_GL_ERROR(
9348 GL_INVALID_VALUE,
9349 "glCreateStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429350 return error::kNoError;
9351 }
9352
[email protected]370eaf12013-05-18 09:19:499353 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079354 if (texture->IsStreamTexture()) {
[email protected]ab09b612013-03-11 22:11:519355 LOCAL_SET_GL_ERROR(
9356 GL_INVALID_OPERATION,
9357 "glCreateStreamTextureCHROMIUM", "is already a stream texture.");
[email protected]b0af4f52011-09-28 22:04:429358 return error::kNoError;
9359 }
9360
[email protected]02965c22013-03-09 02:40:079361 if (texture->target() && texture->target() != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:519362 LOCAL_SET_GL_ERROR(
9363 GL_INVALID_OPERATION,
9364 "glCreateStreamTextureCHROMIUM",
9365 "is already bound to incompatible target.");
[email protected]b0af4f52011-09-28 22:04:429366 return error::kNoError;
9367 }
9368
9369 if (!stream_texture_manager_)
9370 return error::kInvalidArguments;
9371
9372 GLuint object_id = stream_texture_manager_->CreateStreamTexture(
[email protected]02965c22013-03-09 02:40:079373 texture->service_id(), client_id);
[email protected]b0af4f52011-09-28 22:04:429374
9375 if (object_id) {
[email protected]370eaf12013-05-18 09:19:499376 texture_manager()->SetStreamTexture(texture_ref, true);
[email protected]b0af4f52011-09-28 22:04:429377 } else {
[email protected]ab09b612013-03-11 22:11:519378 LOCAL_SET_GL_ERROR(
9379 GL_OUT_OF_MEMORY,
9380 "glCreateStreamTextureCHROMIUM", "failed to create platform texture.");
[email protected]b0af4f52011-09-28 22:04:429381 }
9382
9383 *result = object_id;
9384 return error::kNoError;
9385}
9386
9387error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM(
9388 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359389 const cmds::DestroyStreamTextureCHROMIUM& c) {
[email protected]b0af4f52011-09-28 22:04:429390 GLuint client_id = c.texture;
[email protected]370eaf12013-05-18 09:19:499391 TextureRef* texture_ref = texture_manager()->GetTexture(client_id);
9392 if (texture_ref && texture_ref->texture()->IsStreamTexture()) {
[email protected]b0af4f52011-09-28 22:04:429393 if (!stream_texture_manager_)
9394 return error::kInvalidArguments;
9395
[email protected]370eaf12013-05-18 09:19:499396 stream_texture_manager_->DestroyStreamTexture(texture_ref->service_id());
9397 texture_manager()->SetStreamTexture(texture_ref, false);
[email protected]b0af4f52011-09-28 22:04:429398 } else {
[email protected]ab09b612013-03-11 22:11:519399 LOCAL_SET_GL_ERROR(
9400 GL_INVALID_VALUE,
9401 "glDestroyStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429402 }
9403
9404 return error::kNoError;
9405}
9406
[email protected]e51bdf32011-11-23 22:21:469407#if defined(OS_MACOSX)
9408void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9409 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9410 texture_id);
9411 if (it != texture_to_io_surface_map_.end()) {
9412 // Found a previous IOSurface bound to this texture; release it.
9413 CFTypeRef surface = it->second;
9414 CFRelease(surface);
9415 texture_to_io_surface_map_.erase(it);
9416 }
9417}
9418#endif
9419
9420void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9421 GLenum target, GLsizei width, GLsizei height,
9422 GLuint io_surface_id, GLuint plane) {
9423#if defined(OS_MACOSX)
9424 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:519425 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439426 GL_INVALID_OPERATION,
9427 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:469428 return;
9429 }
9430
9431 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize();
9432 if (!surface_support) {
[email protected]ab09b612013-03-11 22:11:519433 LOCAL_SET_GL_ERROR(
9434 GL_INVALID_OPERATION,
9435 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6.");
[email protected]e51bdf32011-11-23 22:21:469436 return;
9437 }
9438
9439 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9440 // This might be supported in the future, and if we could require
9441 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9442 // could delete a lot of code. For now, perform strict validation so we
9443 // know what's going on.
[email protected]ab09b612013-03-11 22:11:519444 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469445 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439446 "glTexImageIOSurface2DCHROMIUM",
9447 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:469448 return;
9449 }
9450
[email protected]09d50362012-10-18 20:54:379451 // Default target might be conceptually valid, but disallow it to avoid
9452 // accidents.
[email protected]370eaf12013-05-18 09:19:499453 TextureRef* texture_ref = GetTextureInfoForTargetUnlessDefault(target);
9454 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519455 LOCAL_SET_GL_ERROR(
9456 GL_INVALID_OPERATION,
9457 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:469458 return;
9459 }
[email protected]e51bdf32011-11-23 22:21:469460
9461 // Look up the new IOSurface. Note that because of asynchrony
9462 // between processes this might fail; during live resizing the
9463 // plugin process might allocate and release an IOSurface before
9464 // this process gets a chance to look it up. Hold on to any old
9465 // IOSurface in this case.
9466 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id);
9467 if (!surface) {
[email protected]ab09b612013-03-11 22:11:519468 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439469 GL_INVALID_OPERATION,
9470 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:469471 return;
9472 }
9473
9474 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:499475 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:469476
9477 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9478 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:499479 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:469480
9481 CGLContextObj context =
9482 static_cast<CGLContextObj>(context_->GetHandle());
9483
9484 CGLError err = surface_support->CGLTexImageIOSurface2D(
9485 context,
9486 target,
9487 GL_RGBA,
9488 width,
9489 height,
9490 GL_BGRA,
9491 GL_UNSIGNED_INT_8_8_8_8_REV,
9492 surface,
9493 plane);
9494
9495 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:519496 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469497 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439498 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:469499 return;
9500 }
9501
9502 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499503 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:469504 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9505
9506#else
[email protected]ab09b612013-03-11 22:11:519507 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439508 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:469509#endif
9510}
9511
[email protected]97dc7cbe2011-12-06 17:26:179512static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9513 switch (internalformat) {
9514 case GL_RGB565:
9515 return GL_RGB;
9516 case GL_RGBA4:
9517 return GL_RGBA;
9518 case GL_RGB5_A1:
9519 return GL_RGBA;
9520 case GL_RGB8_OES:
9521 return GL_RGB;
9522 case GL_RGBA8_OES:
9523 return GL_RGBA;
9524 case GL_LUMINANCE8_ALPHA8_EXT:
9525 return GL_LUMINANCE_ALPHA;
9526 case GL_LUMINANCE8_EXT:
9527 return GL_LUMINANCE;
9528 case GL_ALPHA8_EXT:
9529 return GL_ALPHA;
9530 case GL_RGBA32F_EXT:
9531 return GL_RGBA;
9532 case GL_RGB32F_EXT:
9533 return GL_RGB;
9534 case GL_ALPHA32F_EXT:
9535 return GL_ALPHA;
9536 case GL_LUMINANCE32F_EXT:
9537 return GL_LUMINANCE;
9538 case GL_LUMINANCE_ALPHA32F_EXT:
9539 return GL_LUMINANCE_ALPHA;
9540 case GL_RGBA16F_EXT:
9541 return GL_RGBA;
9542 case GL_RGB16F_EXT:
9543 return GL_RGB;
9544 case GL_ALPHA16F_EXT:
9545 return GL_ALPHA;
9546 case GL_LUMINANCE16F_EXT:
9547 return GL_LUMINANCE;
9548 case GL_LUMINANCE_ALPHA16F_EXT:
9549 return GL_LUMINANCE_ALPHA;
9550 case GL_BGRA8_EXT:
9551 return GL_BGRA_EXT;
9552 default:
9553 return GL_NONE;
9554 }
9555}
9556
[email protected]43410e92012-04-20 17:06:289557void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:039558 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:549559 GLenum internal_format, GLenum dest_type) {
[email protected]370eaf12013-05-18 09:19:499560 TextureRef* dest_texture_ref = GetTexture(dest_id);
9561 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:289562
[email protected]370eaf12013-05-18 09:19:499563 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:519564 LOCAL_SET_GL_ERROR(
9565 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:289566 return;
9567 }
9568
9569 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:519570 LOCAL_SET_GL_ERROR(
9571 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:289572 return;
9573 }
9574
[email protected]370eaf12013-05-18 09:19:499575 Texture* source_texture = source_texture_ref->texture();
9576 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079577 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:259578 (source_texture->target() != GL_TEXTURE_2D &&
9579 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]ab09b612013-03-11 22:11:519580 LOCAL_SET_GL_ERROR(
9581 GL_INVALID_VALUE,
9582 "glCopyTextureCHROMIUM", "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:039583 return;
9584 }
9585
[email protected]43410e92012-04-20 17:06:289586 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:289587
[email protected]9bc9a2e82013-04-03 03:56:259588 if (source_texture->target() == GL_TEXTURE_2D) {
9589 if (!source_texture->GetLevelSize(GL_TEXTURE_2D, 0, &source_width,
9590 &source_height)) {
9591 LOCAL_SET_GL_ERROR(
9592 GL_INVALID_VALUE,
9593 "glCopyTextureChromium", "source texture has no level 0");
9594 return;
9595 }
9596
9597 // Check that this type of texture is allowed.
9598 if (!texture_manager()->ValidForTarget(GL_TEXTURE_2D, level, source_width,
9599 source_height, 1)) {
9600 LOCAL_SET_GL_ERROR(
9601 GL_INVALID_VALUE,
9602 "glCopyTextureCHROMIUM", "Bad dimensions");
9603 return;
9604 }
[email protected]43410e92012-04-20 17:06:289605 }
9606
[email protected]377976552013-05-14 23:32:569607 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9608 DCHECK(stream_texture_manager_);
9609 StreamTexture* stream_tex =
9610 stream_texture_manager_->LookupStreamTexture(
9611 source_texture->service_id());
9612 if (!stream_tex) {
9613 LOCAL_SET_GL_ERROR(
9614 GL_INVALID_VALUE,
9615 "glCopyTextureChromium", "Stream texture lookup failed");
9616 return;
9617 }
9618 gfx::Size size = stream_tex->GetSize();
9619 source_width = size.width();
9620 source_height = size.height();
9621 if (source_width <= 0 || source_height <= 0) {
9622 LOCAL_SET_GL_ERROR(
9623 GL_INVALID_VALUE,
9624 "glCopyTextureChromium", "invalid streamtexture size");
9625 return;
9626 }
9627 }
9628
[email protected]cf6b8f62012-05-25 21:43:379629 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9630 // needed because it takes 10s of milliseconds to initialize.
9631 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:519632 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:379633 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:279634 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:379635 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:519636 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:379637 return;
9638 }
9639
[email protected]a4a6bdd12013-04-19 20:46:549640 GLenum dest_type_previous;
[email protected]0a1e9ad2012-05-04 21:13:039641 GLenum dest_internal_format;
[email protected]02965c22013-03-09 02:40:079642 bool dest_level_defined = dest_texture->GetLevelSize(
9643 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:289644
[email protected]0a1e9ad2012-05-04 21:13:039645 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:549646 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:079647 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:039648 }
9649
[email protected]0a1e9ad2012-05-04 21:13:039650 // Resize the destination texture to the dimensions of the source texture.
9651 if (!dest_level_defined || dest_width != source_width ||
9652 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:549653 dest_internal_format != internal_format ||
9654 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:289655 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:519656 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:079657 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:389658 glTexImage2D(
[email protected]43410e92012-04-20 17:06:289659 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:039660 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:519661 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:039662 if (error != GL_NO_ERROR) {
9663 RestoreCurrentTexture2DBindings();
[email protected]43410e92012-04-20 17:06:289664 return;
[email protected]0a1e9ad2012-05-04 21:13:039665 }
[email protected]43410e92012-04-20 17:06:289666
9667 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499668 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:039669 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:259670 } else {
[email protected]02965c22013-03-09 02:40:079671 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:499672 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:289673 }
9674
[email protected]5394a4102013-04-18 05:41:379675 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
9676 // before presenting.
9677 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9678 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
9679 // instead of using default matrix crbug.com/226218.
9680 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
9681 0.0f, 1.0f, 0.0f, 0.0f,
9682 0.0f, 0.0f, 1.0f, 0.0f,
9683 0.0f, 0.0f, 0.0f, 1.0f};
9684 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
9685 this,
9686 source_texture->target(),
9687 dest_texture->target(),
9688 source_texture->service_id(),
9689 dest_texture->service_id(), level,
9690 source_width, source_height,
9691 unpack_flip_y_,
9692 unpack_premultiply_alpha_,
9693 unpack_unpremultiply_alpha_,
9694 default_matrix);
9695 } else {
9696 copy_texture_CHROMIUM_->DoCopyTexture(
9697 this,
9698 source_texture->target(),
9699 dest_texture->target(),
9700 source_texture->service_id(),
9701 dest_texture->service_id(), level,
9702 source_width, source_height,
9703 unpack_flip_y_,
9704 unpack_premultiply_alpha_,
9705 unpack_unpremultiply_alpha_);
9706 }
[email protected]43410e92012-04-20 17:06:289707}
9708
[email protected]97dc7cbe2011-12-06 17:26:179709static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
9710 switch (internalformat) {
9711 case GL_RGB565:
9712 return GL_UNSIGNED_SHORT_5_6_5;
9713 case GL_RGBA4:
9714 return GL_UNSIGNED_SHORT_4_4_4_4;
9715 case GL_RGB5_A1:
9716 return GL_UNSIGNED_SHORT_5_5_5_1;
9717 case GL_RGB8_OES:
9718 return GL_UNSIGNED_BYTE;
9719 case GL_RGBA8_OES:
9720 return GL_UNSIGNED_BYTE;
9721 case GL_LUMINANCE8_ALPHA8_EXT:
9722 return GL_UNSIGNED_BYTE;
9723 case GL_LUMINANCE8_EXT:
9724 return GL_UNSIGNED_BYTE;
9725 case GL_ALPHA8_EXT:
9726 return GL_UNSIGNED_BYTE;
9727 case GL_RGBA32F_EXT:
9728 return GL_FLOAT;
9729 case GL_RGB32F_EXT:
9730 return GL_FLOAT;
9731 case GL_ALPHA32F_EXT:
9732 return GL_FLOAT;
9733 case GL_LUMINANCE32F_EXT:
9734 return GL_FLOAT;
9735 case GL_LUMINANCE_ALPHA32F_EXT:
9736 return GL_FLOAT;
9737 case GL_RGBA16F_EXT:
9738 return GL_HALF_FLOAT_OES;
9739 case GL_RGB16F_EXT:
9740 return GL_HALF_FLOAT_OES;
9741 case GL_ALPHA16F_EXT:
9742 return GL_HALF_FLOAT_OES;
9743 case GL_LUMINANCE16F_EXT:
9744 return GL_HALF_FLOAT_OES;
9745 case GL_LUMINANCE_ALPHA16F_EXT:
9746 return GL_HALF_FLOAT_OES;
9747 case GL_BGRA8_EXT:
9748 return GL_UNSIGNED_BYTE;
9749 default:
9750 return GL_NONE;
9751 }
9752}
9753
9754void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:449755 GLenum target,
9756 GLint levels,
9757 GLenum internal_format,
9758 GLsizei width,
9759 GLsizei height) {
[email protected]43ed3a72012-05-30 22:55:389760 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT");
[email protected]80eb6b52012-01-19 00:14:419761 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]97dc7cbe2011-12-06 17:26:179762 TextureManager::ComputeMipMapCount(width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:519763 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439764 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:179765 return;
9766 }
[email protected]370eaf12013-05-18 09:19:499767 TextureRef* texture_ref = GetTextureInfoForTarget(target);
9768 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519769 LOCAL_SET_GL_ERROR(
9770 GL_INVALID_OPERATION,
9771 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:179772 return;
9773 }
[email protected]370eaf12013-05-18 09:19:499774 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079775 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:429776 clear_state_dirty_ = true;
[email protected]97dc7cbe2011-12-06 17:26:179777 }
[email protected]02965c22013-03-09 02:40:079778 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519779 LOCAL_SET_GL_ERROR(
9780 GL_INVALID_OPERATION,
9781 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:179782 return;
9783 }
[email protected]7989c9e2013-01-23 06:39:269784
9785 GLenum format = ExtractFormatFromStorageFormat(internal_format);
9786 GLenum type = ExtractTypeFromStorageFormat(internal_format);
9787
9788 {
9789 GLsizei level_width = width;
9790 GLsizei level_height = height;
9791 uint32 estimated_size = 0;
9792 for (int ii = 0; ii < levels; ++ii) {
9793 uint32 level_size = 0;
9794 if (!GLES2Util::ComputeImageDataSizes(
9795 level_width, level_height, format, type, state_.unpack_alignment,
9796 &estimated_size, NULL, NULL) ||
9797 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519798 LOCAL_SET_GL_ERROR(
9799 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269800 return;
9801 }
9802 level_width = std::max(1, level_width >> 1);
9803 level_height = std::max(1, level_height >> 1);
9804 }
9805 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519806 LOCAL_SET_GL_ERROR(
9807 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:269808 return;
9809 }
9810 }
9811
[email protected]ab09b612013-03-11 22:11:519812 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:389813 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:519814 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:179815 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:159816 GLsizei level_width = width;
9817 GLsizei level_height = height;
9818 for (int ii = 0; ii < levels; ++ii) {
9819 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499820 texture_ref, target, ii, format,
9821 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:159822 level_width = std::max(1, level_width >> 1);
9823 level_height = std::max(1, level_height >> 1);
9824 }
[email protected]02965c22013-03-09 02:40:079825 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:179826 }
[email protected]97dc7cbe2011-12-06 17:26:179827}
[email protected]e51bdf32011-11-23 22:21:469828
[email protected]78b514b2012-05-01 21:50:599829error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359830 uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) {
[email protected]78b514b2012-05-01 21:50:599831 MailboxName name;
9832 mailbox_manager()->GenerateMailboxName(&name);
9833 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
9834 Bucket* bucket = CreateBucket(bucket_id);
9835
9836 bucket->SetSize(GL_MAILBOX_SIZE_CHROMIUM);
9837 bucket->SetData(&name, 0, GL_MAILBOX_SIZE_CHROMIUM);
9838
9839 return error::kNoError;
9840}
9841
9842void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
9843 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:029844 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:329845 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:029846 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
9847
[email protected]370eaf12013-05-18 09:19:499848 TextureRef* texture_ref = GetTextureInfoForTarget(target);
9849 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519850 LOCAL_SET_GL_ERROR(
9851 GL_INVALID_OPERATION,
9852 "glProduceTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599853 return;
9854 }
9855
[email protected]370eaf12013-05-18 09:19:499856 TextureDefinition* definition = texture_manager()->Save(texture_ref);
[email protected]78b514b2012-05-01 21:50:599857 if (!definition) {
[email protected]ab09b612013-03-11 22:11:519858 LOCAL_SET_GL_ERROR(
9859 GL_INVALID_OPERATION,
9860 "glProduceTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599861 return;
9862 }
9863
9864 if (!group_->mailbox_manager()->ProduceTexture(
9865 target,
9866 *reinterpret_cast<const MailboxName*>(mailbox),
9867 definition,
9868 texture_manager())) {
[email protected]02965c22013-03-09 02:40:079869 bool success = texture_manager()->Restore(
[email protected]370eaf12013-05-18 09:19:499870 "glProductTextureCHROMIUM", this, texture_ref, definition);
[email protected]78b514b2012-05-01 21:50:599871 DCHECK(success);
[email protected]ab09b612013-03-11 22:11:519872 LOCAL_SET_GL_ERROR(
9873 GL_INVALID_OPERATION,
9874 "glProduceTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599875 return;
9876 }
9877
[email protected]370eaf12013-05-18 09:19:499878 glBindTexture(texture_ref->texture()->target(), texture_ref->service_id());
[email protected]78b514b2012-05-01 21:50:599879}
9880
9881void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
9882 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:029883 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:329884 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:029885 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
9886
[email protected]370eaf12013-05-18 09:19:499887 TextureRef* texture_ref = GetTextureInfoForTarget(target);
9888 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519889 LOCAL_SET_GL_ERROR(
9890 GL_INVALID_OPERATION,
9891 "glConsumeTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599892 return;
9893 }
9894
9895 scoped_ptr<TextureDefinition> definition(
9896 group_->mailbox_manager()->ConsumeTexture(
9897 target,
9898 *reinterpret_cast<const MailboxName*>(mailbox)));
9899 if (!definition.get()) {
[email protected]ab09b612013-03-11 22:11:519900 LOCAL_SET_GL_ERROR(
9901 GL_INVALID_OPERATION,
9902 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599903 return;
9904 }
9905
[email protected]02965c22013-03-09 02:40:079906 if (!texture_manager()->Restore(
[email protected]370eaf12013-05-18 09:19:499907 "glConsumeTextureCHROMIUM", this, texture_ref, definition.release())) {
[email protected]ab09b612013-03-11 22:11:519908 LOCAL_SET_GL_ERROR(
9909 GL_INVALID_OPERATION,
9910 "glConsumeTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599911 return;
9912 }
[email protected]78b514b2012-05-01 21:50:599913}
9914
[email protected]d2a0e1a2012-08-12 02:25:019915void GLES2DecoderImpl::DoInsertEventMarkerEXT(
9916 GLsizei length, const GLchar* marker) {
9917 if (!marker) {
9918 marker = "";
9919 }
9920 debug_marker_manager_.SetMarker(
9921 length ? std::string(marker, length) : std::string(marker));
9922}
9923
9924void GLES2DecoderImpl::DoPushGroupMarkerEXT(
9925 GLsizei length, const GLchar* marker) {
9926 if (!marker) {
9927 marker = "";
9928 }
9929 debug_marker_manager_.PushGroup(
9930 length ? std::string(marker, length) : std::string(marker));
9931}
9932
9933void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
9934 debug_marker_manager_.PopGroup();
9935}
9936
[email protected]09d50362012-10-18 20:54:379937void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
9938 GLenum target, GLint image_id) {
9939 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
9940 if (target != GL_TEXTURE_2D) {
9941 // This might be supported in the future.
[email protected]ab09b612013-03-11 22:11:519942 LOCAL_SET_GL_ERROR(
[email protected]09d50362012-10-18 20:54:379943 GL_INVALID_OPERATION,
9944 "glBindTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9945 return;
9946 }
9947
9948 // Default target might be conceptually valid, but disallow it to avoid
9949 // accidents.
[email protected]370eaf12013-05-18 09:19:499950 TextureRef* texture_ref = GetTextureInfoForTargetUnlessDefault(target);
9951 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519952 LOCAL_SET_GL_ERROR(
9953 GL_INVALID_OPERATION,
9954 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:379955 return;
9956 }
9957
9958 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
9959 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:519960 LOCAL_SET_GL_ERROR(
9961 GL_INVALID_OPERATION,
9962 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:379963 return;
9964 }
9965
[email protected]b8160812013-04-09 00:41:049966 {
9967 ScopedGLErrorSuppressor suppressor(
9968 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", this);
9969 if (!gl_image->BindTexImage()) {
9970 LOCAL_SET_GL_ERROR(
9971 GL_INVALID_OPERATION,
9972 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
9973 return;
9974 }
[email protected]09d50362012-10-18 20:54:379975 }
9976
9977 gfx::Size size = gl_image->GetSize();
9978 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499979 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:379980 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:499981 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:379982}
9983
9984void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
9985 GLenum target, GLint image_id) {
9986 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
9987 if (target != GL_TEXTURE_2D) {
9988 // This might be supported in the future.
[email protected]ab09b612013-03-11 22:11:519989 LOCAL_SET_GL_ERROR(
[email protected]09d50362012-10-18 20:54:379990 GL_INVALID_OPERATION,
9991 "glReleaseTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9992 return;
9993 }
9994
9995 // Default target might be conceptually valid, but disallow it to avoid
9996 // accidents.
[email protected]370eaf12013-05-18 09:19:499997 TextureRef* texture_ref = GetTextureInfoForTargetUnlessDefault(target);
9998 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519999 LOCAL_SET_GL_ERROR(
10000 GL_INVALID_OPERATION,
10001 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710002 return;
10003 }
10004
10005 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10006 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110007 LOCAL_SET_GL_ERROR(
10008 GL_INVALID_OPERATION,
10009 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710010 return;
10011 }
10012
10013 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4910014 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3710015 return;
10016
[email protected]b8160812013-04-09 00:41:0410017 {
10018 ScopedGLErrorSuppressor suppressor(
10019 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", this);
10020 gl_image->ReleaseTexImage();
10021 }
[email protected]09d50362012-10-18 20:54:3710022
10023 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910024 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3710025 GL_RGBA, GL_UNSIGNED_BYTE, false);
10026}
[email protected]d2a0e1a2012-08-12 02:25:0110027
[email protected]94307712012-11-16 23:26:1110028error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510029 uint32 immediate_data_size, const cmds::TraceBeginCHROMIUM& c) {
[email protected]94307712012-11-16 23:26:1110030 Bucket* bucket = GetBucket(c.bucket_id);
10031 if (!bucket || bucket->size() == 0) {
10032 return error::kInvalidArguments;
10033 }
10034 std::string command_name;
10035 if (!bucket->GetAsString(&command_name)) {
10036 return error::kInvalidArguments;
10037 }
[email protected]fb97b662013-02-20 23:02:1410038 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
10039 if (!gpu_tracer_->Begin(command_name)) {
[email protected]ab09b612013-03-11 22:11:5110040 LOCAL_SET_GL_ERROR(
10041 GL_INVALID_OPERATION,
10042 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1410043 return error::kNoError;
10044 }
[email protected]94307712012-11-16 23:26:1110045 return error::kNoError;
10046}
10047
10048void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1410049 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5110050 LOCAL_SET_GL_ERROR(
10051 GL_INVALID_OPERATION,
10052 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1110053 return;
10054 }
[email protected]fb97b662013-02-20 23:02:1410055 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
10056 gpu_tracer_->End();
[email protected]94307712012-11-16 23:26:1110057}
10058
[email protected]2f143d482013-03-14 18:04:4910059void GLES2DecoderImpl::DoDrawBuffersEXT(
10060 GLsizei count, const GLenum* bufs) {
10061 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10062 LOCAL_SET_GL_ERROR(
10063 GL_INVALID_VALUE,
10064 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10065 return;
10066 }
10067
10068 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10069 if (framebuffer) {
10070 for (GLsizei i = 0; i < count; ++i) {
10071 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10072 bufs[i] != GL_NONE) {
10073 LOCAL_SET_GL_ERROR(
10074 GL_INVALID_OPERATION,
10075 "glDrawBuffersEXT",
10076 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10077 return;
10078 }
10079 }
10080 glDrawBuffersARB(count, bufs);
10081 framebuffer->SetDrawBuffers(count, bufs);
10082 } else { // backbuffer
10083 if (count > 1 ||
10084 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10085 LOCAL_SET_GL_ERROR(
10086 GL_INVALID_OPERATION,
10087 "glDrawBuffersEXT",
10088 "more than one buffer or bufs not GL_NONE or GL_BACK");
10089 return;
10090 }
10091 GLenum mapped_buf = bufs[0];
10092 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10093 bufs[0] == GL_BACK) {
10094 mapped_buf = GL_COLOR_ATTACHMENT0;
10095 }
10096 glDrawBuffersARB(count, &mapped_buf);
10097 group_->set_draw_buffer(bufs[0]);
10098 }
10099}
10100
[email protected]32145a92012-12-17 09:01:5910101bool GLES2DecoderImpl::ValidateAsyncTransfer(
10102 const char* function_name,
[email protected]02965c22013-03-09 02:40:0710103 Texture* texture,
[email protected]32145a92012-12-17 09:01:5910104 GLenum target,
10105 GLint level,
10106 const void * data) {
10107 // We only support async uploads to 2D textures for now.
10108 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110109 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910110 return false;
10111 }
10112 // We only support uploads to level zero for now.
10113 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110114 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910115 return false;
10116 }
10117 // A transfer buffer must be bound, even for asyncTexImage2D.
10118 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110119 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910120 return false;
10121 }
10122 // We only support one async transfer in progress.
[email protected]02965c22013-03-09 02:40:0710123 if (!texture || texture->AsyncTransferIsInProgress()) {
[email protected]ab09b612013-03-11 22:11:5110124 LOCAL_SET_GL_ERROR(
10125 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910126 function_name, "transfer already in progress");
10127 return false;
10128 }
10129 return true;
10130}
10131
[email protected]69023942012-11-30 19:57:1610132error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510133 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610134 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610135 GLenum target = static_cast<GLenum>(c.target);
10136 GLint level = static_cast<GLint>(c.level);
10137 GLint internal_format = static_cast<GLint>(c.internalformat);
10138 GLsizei width = static_cast<GLsizei>(c.width);
10139 GLsizei height = static_cast<GLsizei>(c.height);
10140 GLint border = static_cast<GLint>(c.border);
10141 GLenum format = static_cast<GLenum>(c.format);
10142 GLenum type = static_cast<GLenum>(c.type);
10143 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10144 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10145 uint32 pixels_size;
[email protected]32145a92012-12-17 09:01:5910146
10147 // TODO(epenner): Move this and copies of this memory validation
10148 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1610149 if (!GLES2Util::ComputeImageDataSizes(
10150 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
10151 NULL)) {
10152 return error::kOutOfBounds;
10153 }
10154 const void* pixels = NULL;
10155 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
10156 pixels = GetSharedMemoryAs<const void*>(
10157 pixels_shm_id, pixels_shm_offset, pixels_size);
10158 if (!pixels) {
10159 return error::kOutOfBounds;
10160 }
10161 }
10162
[email protected]32145a92012-12-17 09:01:5910163 // All the normal glTexSubImage2D validation.
10164 if (!ValidateTexImage2D(
10165 "glAsyncTexImage2DCHROMIUM", target, level, internal_format,
10166 width, height, border, format, type, pixels, pixels_size)) {
10167 return error::kNoError;
10168 }
10169
10170 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4910171 TextureRef* texture_ref = GetTextureInfoForTarget(target);
10172 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910173 if (!ValidateAsyncTransfer(
[email protected]02965c22013-03-09 02:40:0710174 "glAsyncTexImage2DCHROMIUM", texture, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910175 return error::kNoError;
10176
10177 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0710178 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5110179 LOCAL_SET_GL_ERROR(
10180 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910181 "glAsyncTexImage2DCHROMIUM", "already defined");
10182 return error::kNoError;
10183 }
10184
[email protected]7989c9e2013-01-23 06:39:2610185 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5110186 LOCAL_SET_GL_ERROR(
10187 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610188 return error::kNoError;
10189 }
10190
[email protected]32145a92012-12-17 09:01:5910191 // We know the memory/size is safe, so get the real shared memory since
10192 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110193 gpu::Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
[email protected]32145a92012-12-17 09:01:5910194 base::SharedMemory* shared_memory = buffer.shared_memory;
10195 uint32 shm_size = buffer.size;
10196 uint32 shm_data_offset = c.pixels_shm_offset;
10197 uint32 shm_data_size = pixels_size;
10198
[email protected]5b3a8e02013-03-13 05:36:4410199 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3810200 AsyncTexImage2DParams tex_params = {
10201 target, level, static_cast<GLenum>(internal_format),
10202 width, height, border, format, type};
10203 AsyncMemoryParams mem_params = {
10204 shared_memory, shm_size, shm_data_offset, shm_data_size};
[email protected]32145a92012-12-17 09:01:5910205
[email protected]5b3a8e02013-03-13 05:36:4410206 // Set up the async state if needed, and make the texture
10207 // immutable so the async state stays valid. The level info
10208 // is set up lazily when the transfer completes.
10209 DCHECK(!texture->GetAsyncTransferState());
[email protected]370eaf12013-05-18 09:19:4910210 texture_ref->SetAsyncTransferState(
[email protected]373cfd02013-04-25 20:20:2110211 make_scoped_ptr(
10212 async_pixel_transfer_delegate_->CreatePixelTransferState(
10213 texture->service_id(),
10214 tex_params)));
[email protected]5b3a8e02013-03-13 05:36:4410215 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5910216
10217 async_pixel_transfer_delegate_->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4410218 texture->GetAsyncTransferState(),
10219 tex_params,
10220 mem_params,
10221 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4910222 // The callback is only invoked if the transfer delegate still
10223 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4410224 // ownership that both of these pointers are valid.
10225 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4910226 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4410227 tex_params));
[email protected]f598f422012-12-07 08:30:0310228 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610229}
10230
10231error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510232 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610233 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610234 GLenum target = static_cast<GLenum>(c.target);
10235 GLint level = static_cast<GLint>(c.level);
10236 GLint xoffset = static_cast<GLint>(c.xoffset);
10237 GLint yoffset = static_cast<GLint>(c.yoffset);
10238 GLsizei width = static_cast<GLsizei>(c.width);
10239 GLsizei height = static_cast<GLsizei>(c.height);
10240 GLenum format = static_cast<GLenum>(c.format);
10241 GLenum type = static_cast<GLenum>(c.type);
[email protected]32145a92012-12-17 09:01:5910242
10243 // TODO(epenner): Move this and copies of this memory validation
10244 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1610245 uint32 data_size;
10246 if (!GLES2Util::ComputeImageDataSizes(
10247 width, height, format, type, state_.unpack_alignment, &data_size,
10248 NULL, NULL)) {
10249 return error::kOutOfBounds;
10250 }
10251 const void* pixels = GetSharedMemoryAs<const void*>(
10252 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5910253
10254 // All the normal glTexSubImage2D validation.
10255 error::Error error = error::kNoError;
10256 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
10257 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
10258 return error;
[email protected]69023942012-11-30 19:57:1610259 }
10260
[email protected]32145a92012-12-17 09:01:5910261 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4910262 TextureRef* texture_ref = GetTextureInfoForTarget(target);
10263 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910264 if (!ValidateAsyncTransfer(
[email protected]02965c22013-03-09 02:40:0710265 "glAsyncTexSubImage2DCHROMIUM", texture, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910266 return error::kNoError;
10267
10268 // Guarantee async textures are always 'cleared' as follows:
10269 // - AsyncTexImage2D can not redefine an existing texture
10270 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
10271 // - AsyncTexSubImage2D clears synchronously if not already cleared.
10272 // - Textures become immutable after an async call.
10273 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0710274 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4910275 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
10276 target, level)) {
[email protected]ab09b612013-03-11 22:11:5110277 LOCAL_SET_GL_ERROR(
10278 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2510279 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5910280 return error::kNoError;
10281 }
10282 }
10283
10284 // We know the memory/size is safe, so get the real shared memory since
10285 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110286 gpu::Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
[email protected]32145a92012-12-17 09:01:5910287 base::SharedMemory* shared_memory = buffer.shared_memory;
10288 uint32 shm_size = buffer.size;
10289 uint32 shm_data_offset = c.data_shm_offset;
10290 uint32 shm_data_size = data_size;
10291
[email protected]5b3a8e02013-03-13 05:36:4410292 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0310293 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5910294 width, height, format, type};
[email protected]2a7568a2013-05-09 23:12:0310295 AsyncMemoryParams mem_params = {shared_memory, shm_size,
[email protected]32145a92012-12-17 09:01:5910296 shm_data_offset, shm_data_size};
[email protected]370eaf12013-05-18 09:19:4910297 AsyncPixelTransferState* state = texture->GetAsyncTransferState();
10298 if (!state) {
[email protected]5b3a8e02013-03-13 05:36:4410299 // TODO(epenner): We may want to enforce exclusive use
10300 // of async APIs in which case this should become an error,
10301 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0310302 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4410303 0, 0, 0, 0, 0, 0};
10304 texture->GetLevelSize(target, level, &define_params.width,
10305 &define_params.height);
10306 texture->GetLevelType(target, level, &define_params.type,
10307 &define_params.internal_format);
10308 // Set up the async state if needed, and make the texture
10309 // immutable so the async state stays valid.
[email protected]370eaf12013-05-18 09:19:4910310 state = async_pixel_transfer_delegate_->CreatePixelTransferState(
10311 texture->service_id(),
10312 define_params);
10313 texture_ref->SetAsyncTransferState(make_scoped_ptr(state));
[email protected]5b3a8e02013-03-13 05:36:4410314 texture->SetImmutable(true);
10315 }
10316
[email protected]32145a92012-12-17 09:01:5910317 async_pixel_transfer_delegate_->AsyncTexSubImage2D(
[email protected]370eaf12013-05-18 09:19:4910318 state, tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5910319 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610320}
10321
[email protected]a00c1f742013-03-05 17:02:1610322error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
10323 uint32 immediate_data_size, const cmds::WaitAsyncTexImage2DCHROMIUM& c) {
10324 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10325 GLenum target = static_cast<GLenum>(c.target);
10326
10327 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110328 LOCAL_SET_GL_ERROR(
10329 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1610330 return error::kNoError;
10331 }
[email protected]370eaf12013-05-18 09:19:4910332 TextureRef* texture_ref = GetTextureInfoForTarget(target);
10333 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110334 LOCAL_SET_GL_ERROR(
10335 GL_INVALID_OPERATION,
10336 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1610337 return error::kNoError;
10338 }
[email protected]370eaf12013-05-18 09:19:4910339 AsyncPixelTransferState* state =
10340 texture_ref->texture()->GetAsyncTransferState();
10341 if (!state) {
10342 LOCAL_SET_GL_ERROR(
10343 GL_INVALID_OPERATION,
10344 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
10345 return error::kNoError;
10346 }
10347 async_pixel_transfer_delegate_->WaitForTransferCompletion(state);
[email protected]69a8701e2013-03-07 21:31:0910348 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1610349 return error::kNoError;
10350}
10351
[email protected]96449d2c2009-11-25 00:01:3210352// Include the auto-generated part of this file. We split this because it means
10353// we can easily edit the non-auto generated parts right here in this file
10354// instead of having to edit some template or the code generator.
10355#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
10356
10357} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2510358} // namespace gpu