blob: 6bfcc1880c650be8f2316d7a17c39e995ad88664 [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]a93bb842010-02-16 23:03:4755#include "gpu/command_buffer/service/texture_manager.h"
[email protected]d8ea9772011-07-11 18:11:4356#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]944b62f32012-09-27 02:20:4657#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]2a7568a2013-05-09 23:12:0358#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
[email protected]85a4ac22013-05-31 01:58:4759#include "gpu/command_buffer/service/async_pixel_transfer_manager.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]729c0b42013-05-26 02:05:07564 const base::Callback<void(gfx::Size, float)>& 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;
[email protected]85a4ac22013-05-31 01:58:47578 virtual void SetAsyncPixelTransferDelegateForTest(
[email protected]2a7568a2013-05-09 23:12:03579 AsyncPixelTransferDelegate* delegate) OVERRIDE;
[email protected]85a4ac22013-05-31 01:58:47580 virtual AsyncPixelTransferManager*
581 GetAsyncPixelTransferManager() OVERRIDE;
582 virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE;
[email protected]69a8701e2013-03-07 21:31:09583 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59584
[email protected]1318e922010-09-17 22:03:16585 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00586 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48587
[email protected]63b465922012-09-06 02:04:52588 virtual uint32 GetTextureUploadCount() OVERRIDE;
589 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
590 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30591 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52592
[email protected]8e3e0662010-08-23 18:46:30593 // Restores the current state to the user's settings.
594 void RestoreCurrentFramebufferBindings();
595 void RestoreCurrentRenderbufferBindings();
596 void RestoreCurrentTexture2DBindings();
597
[email protected]297ca1c2011-06-20 23:08:46598 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
599 void ApplyDirtyState();
600
601 // These check the state of the currently bound framebuffer or the
602 // backbuffer if no framebuffer is bound.
603 bool BoundFramebufferHasColorAttachmentWithAlpha();
604 bool BoundFramebufferHasDepthAttachment();
605 bool BoundFramebufferHasStencilAttachment();
606
[email protected]b8e97b62012-09-30 15:09:00607 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43608
[email protected]96449d2c2009-11-25 00:01:32609 private:
[email protected]70d34263c2013-01-09 00:27:45610 friend class ScopedFrameBufferBinder;
[email protected]6217d392010-03-25 22:08:35611 friend class ScopedGLErrorSuppressor;
[email protected]34ff8b0c2010-10-01 20:06:02612 friend class ScopedResolvedFrameBufferBinder;
[email protected]63b465922012-09-06 02:04:52613 friend class ScopedTextureUploadTimer;
[email protected]ed9f9cd2013-02-27 21:12:35614 friend class BackTexture;
615 friend class BackRenderbuffer;
616 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35617
[email protected]c2f8c8402010-12-06 18:07:24618 // Initialize or re-initialize the shader translator.
619 bool InitializeShaderTranslator();
620
[email protected]302ce6d2011-07-07 23:28:11621 void UpdateCapabilities();
622
[email protected]ae51d192010-04-27 00:48:03623 // Helpers for the glGen and glDelete functions.
624 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
625 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
626 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
627 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
628 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
629 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
630 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
631 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53632 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
633 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46634 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
635 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47636
[email protected]70d34263c2013-01-09 00:27:45637 // Workarounds
638 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51639 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45640
[email protected]3916c97e2010-02-25 03:20:50641 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50642 BufferManager* buffer_manager() {
643 return group_->buffer_manager();
644 }
645
[email protected]a25fa872010-03-25 02:57:58646 RenderbufferManager* renderbuffer_manager() {
647 return group_->renderbuffer_manager();
648 }
649
650 FramebufferManager* framebuffer_manager() {
651 return group_->framebuffer_manager();
652 }
653
[email protected]3916c97e2010-02-25 03:20:50654 ProgramManager* program_manager() {
655 return group_->program_manager();
656 }
657
658 ShaderManager* shader_manager() {
659 return group_->shader_manager();
660 }
661
[email protected]29a4d902013-02-26 20:18:06662 const TextureManager* texture_manager() const {
663 return group_->texture_manager();
664 }
665
[email protected]3916c97e2010-02-25 03:20:50666 TextureManager* texture_manager() {
667 return group_->texture_manager();
668 }
669
[email protected]78b514b2012-05-01 21:50:59670 MailboxManager* mailbox_manager() {
671 return group_->mailbox_manager();
672 }
673
[email protected]09d50362012-10-18 20:54:37674 ImageManager* image_manager() {
675 return group_->image_manager();
676 }
677
[email protected]944b62f32012-09-27 02:20:46678 VertexArrayManager* vertex_array_manager() {
679 return vertex_array_manager_.get();
680 }
681
[email protected]7989c9e2013-01-23 06:39:26682 MemoryTracker* memory_tracker() {
683 return group_->memory_tracker();
684 }
685
686 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
687 MemoryTracker* tracker = memory_tracker();
688 if (tracker) {
689 return tracker->EnsureGPUMemoryAvailable(estimated_size);
690 }
691 return true;
692 }
693
[email protected]34ff8b0c2010-10-01 20:06:02694 bool IsOffscreenBufferMultisampled() const {
695 return offscreen_target_samples_ > 1;
696 }
697
[email protected]ed9f9cd2013-02-27 21:12:35698 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49699 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03700 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35701 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47702 }
703
704 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49705 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07706 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47707 }
708
709 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35710 void RemoveTexture(GLuint client_id) {
711 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50712 }
[email protected]a93bb842010-02-16 23:03:47713
[email protected]d37231fa2010-04-09 21:16:02714 // Get the size (in pixels) of the currently bound frame buffer (either FBO
715 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30716 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02717
[email protected]9edc6b22010-12-23 02:00:26718 // Get the format of the currently bound frame buffer (either FBO or regular
719 // back buffer)
720 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46721 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26722
[email protected]a93bb842010-02-16 23:03:47723 // Wrapper for CompressedTexImage2D commands.
724 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37725 GLenum target,
726 GLint level,
727 GLenum internal_format,
728 GLsizei width,
729 GLsizei height,
730 GLint border,
731 GLsizei image_size,
732 const void* data);
[email protected]a93bb842010-02-16 23:03:47733
[email protected]cadde4a2010-07-31 17:10:43734 // Wrapper for CompressedTexSubImage2D.
735 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37736 GLenum target,
737 GLint level,
738 GLint xoffset,
739 GLint yoffset,
740 GLsizei width,
741 GLsizei height,
742 GLenum format,
743 GLsizei imageSize,
744 const void * data);
[email protected]cadde4a2010-07-31 17:10:43745
746 // Wrapper for CopyTexImage2D.
747 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37748 GLenum target,
749 GLint level,
750 GLenum internal_format,
751 GLint x,
752 GLint y,
753 GLsizei width,
754 GLsizei height,
755 GLint border);
[email protected]cadde4a2010-07-31 17:10:43756
[email protected]6d792ee12013-05-15 00:40:56757 // Wrapper for SwapBuffers.
758 void DoSwapBuffers();
759
[email protected]cadde4a2010-07-31 17:10:43760 // Wrapper for CopyTexSubImage2D.
761 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37762 GLenum target,
763 GLint level,
764 GLint xoffset,
765 GLint yoffset,
766 GLint x,
767 GLint y,
768 GLsizei width,
769 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43770
[email protected]f598f422012-12-07 08:30:03771 // Validation for TexImage2D commands.
772 bool ValidateTexImage2D(
773 const char* function_name,
[email protected]09d50362012-10-18 20:54:37774 GLenum target,
775 GLint level,
776 GLenum internal_format,
777 GLsizei width,
778 GLsizei height,
779 GLint border,
780 GLenum format,
781 GLenum type,
782 const void* pixels,
783 uint32 pixels_size);
[email protected]a93bb842010-02-16 23:03:47784
[email protected]f598f422012-12-07 08:30:03785 // Wrapper for TexImage2D commands.
786 void DoTexImage2D(
787 GLenum target,
788 GLint level,
789 GLenum internal_format,
790 GLsizei width,
791 GLsizei height,
792 GLint border,
793 GLenum format,
794 GLenum type,
795 const void* pixels,
796 uint32 pixels_size);
797
798 // Validation for TexSubImage2D.
799 bool ValidateTexSubImage2D(
800 error::Error* error,
801 const char* function_name,
802 GLenum target,
803 GLint level,
804 GLint xoffset,
805 GLint yoffset,
806 GLsizei width,
807 GLsizei height,
808 GLenum format,
809 GLenum type,
810 const void * data);
811
[email protected]cadde4a2010-07-31 17:10:43812 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03813 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37814 GLenum target,
815 GLint level,
816 GLint xoffset,
817 GLint yoffset,
818 GLsizei width,
819 GLsizei height,
820 GLenum format,
821 GLenum type,
822 const void * data);
[email protected]cadde4a2010-07-31 17:10:43823
[email protected]32145a92012-12-17 09:01:59824 // Extra validation for async tex(Sub)Image2D.
825 bool ValidateAsyncTransfer(
826 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47827 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59828 GLenum target,
829 GLint level,
830 const void * data);
831
[email protected]e51bdf32011-11-23 22:21:46832 // Wrapper for TexImageIOSurface2DCHROMIUM.
833 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37834 GLenum target,
835 GLsizei width,
836 GLsizei height,
837 GLuint io_surface_id,
838 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46839
[email protected]43410e92012-04-20 17:06:28840 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37841 GLenum target,
842 GLuint source_id,
843 GLuint target_id,
844 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54845 GLenum internal_format,
846 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28847
[email protected]97dc7cbe2011-12-06 17:26:17848 // Wrapper for TexStorage2DEXT.
849 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37850 GLenum target,
851 GLint levels,
852 GLenum internal_format,
853 GLsizei width,
854 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17855
[email protected]78b514b2012-05-01 21:50:59856 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
857 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
858
[email protected]09d50362012-10-18 20:54:37859 void DoBindTexImage2DCHROMIUM(
860 GLenum target,
861 GLint image_id);
862 void DoReleaseTexImage2DCHROMIUM(
863 GLenum target,
864 GLint image_id);
865
[email protected]94307712012-11-16 23:26:11866 void DoTraceEndCHROMIUM(void);
867
[email protected]2f143d482013-03-14 18:04:49868 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
869
[email protected]ed9f9cd2013-02-27 21:12:35870 // Creates a Program for the given program.
871 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57872 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35873 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47874 }
875
[email protected]07f54fcc2009-12-22 02:46:30876 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35877 Program* GetProgram(GLuint client_id) {
878 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46879 }
[email protected]07f54fcc2009-12-22 02:46:30880
[email protected]cae20172012-12-07 00:06:19881#if defined(NDEBUG)
882 void LogClientServiceMapping(
883 const char* /* function_name */,
884 GLuint /* client_id */,
885 GLuint /* service_id */) {
886 }
887 template<typename T>
888 void LogClientServiceForInfo(
889 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
890 }
891#else
892 void LogClientServiceMapping(
893 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:26894 if (service_logging_) {
[email protected]1d82e822013-04-10 21:32:32895 DLOG(INFO) << "[" << logger_.GetLogPrefix() << "] " << function_name
[email protected]2a22fe72012-12-07 04:21:26896 << ": client_id = " << client_id
897 << ", service_id = " << service_id;
898 }
[email protected]cae20172012-12-07 00:06:19899 }
900 template<typename T>
901 void LogClientServiceForInfo(
902 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:26903 if (info) {
[email protected]cae20172012-12-07 00:06:19904 LogClientServiceMapping(function_name, client_id, info->service_id());
905 }
906 }
907#endif
908
[email protected]6b8cf1a2010-05-06 16:13:58909 // Gets the program info for the given program. If it's not a program
910 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:35911 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:58912 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42913 Program* program = GetProgram(client_id);
914 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:35915 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:51916 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43917 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:58918 } else {
[email protected]ab09b612013-03-11 22:11:51919 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:58920 }
921 }
[email protected]df37b9932013-03-08 05:21:42922 LogClientServiceForInfo(program, client_id, function_name);
923 return program;
[email protected]6b8cf1a2010-05-06 16:13:58924 }
925
926
[email protected]ed9f9cd2013-02-27 21:12:35927 // Creates a Shader for the given shader.
928 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:57929 GLuint client_id,
930 GLuint service_id,
931 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:35932 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:57933 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:31934 }
935
936 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35937 Shader* GetShader(GLuint client_id) {
938 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:31939 }
940
[email protected]6b8cf1a2010-05-06 16:13:58941 // Gets the shader info for the given shader. If it's not a shader generates a
942 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:35943 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:58944 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42945 Shader* shader = GetShader(client_id);
946 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:35947 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:51948 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43949 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:58950 } else {
[email protected]ab09b612013-03-11 22:11:51951 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43952 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:58953 }
954 }
[email protected]df37b9932013-03-08 05:21:42955 LogClientServiceForInfo(shader, client_id, function_name);
956 return shader;
[email protected]6b8cf1a2010-05-06 16:13:58957 }
958
[email protected]a93bb842010-02-16 23:03:47959 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:35960 void CreateBuffer(GLuint client_id, GLuint service_id) {
961 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47962 }
963
[email protected]07f54fcc2009-12-22 02:46:30964 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:21965 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:07966 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
967 return buffer;
[email protected]1d32bc82010-01-13 22:06:46968 }
[email protected]07f54fcc2009-12-22 02:46:30969
[email protected]a93bb842010-02-16 23:03:47970 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
971 // on glDeleteBuffers so we can make sure the user does not try to render
972 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:35973 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:47974
[email protected]a25fa872010-03-25 02:57:58975 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:35976 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
977 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:58978 }
979
980 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:06981 Framebuffer* GetFramebuffer(GLuint client_id) {
982 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:58983 }
984
985 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:35986 void RemoveFramebuffer(GLuint client_id) {
987 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:58988 }
989
990 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:35991 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
992 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:03993 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:58994 }
995
996 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:27997 Renderbuffer* GetRenderbuffer(GLuint client_id) {
998 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:58999 }
1000
1001 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351002 void RemoveRenderbuffer(GLuint client_id) {
1003 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581004 }
1005
[email protected]944b62f32012-09-27 02:20:461006 // Gets the vertex attrib manager for the given vertex array.
1007 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1008 VertexAttribManager* info =
1009 vertex_array_manager()->GetVertexAttribManager(client_id);
1010 return info;
1011 }
1012
1013 // Removes the vertex attrib manager for the given vertex array.
1014 void RemoveVertexAttribManager(GLuint client_id) {
1015 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1016 }
1017
1018 // Creates a vertex attrib manager for the given vertex array.
1019 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) {
1020 return vertex_array_manager()->CreateVertexAttribManager(
1021 client_id, service_id, group_->max_vertex_attribs());
1022 }
1023
[email protected]258a3313f2011-10-18 20:13:571024 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331025 void DoBindUniformLocationCHROMIUM(
1026 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571027
[email protected]558847a2010-03-24 07:02:541028 error::Error GetAttribLocationHelper(
1029 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1030 const std::string& name_str);
1031
1032 error::Error GetUniformLocationHelper(
1033 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1034 const std::string& name_str);
1035
[email protected]3916c97e2010-02-25 03:20:501036 // Helper for glShaderSource.
1037 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031038 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301039
[email protected]0d6bfdc2011-11-02 01:32:201040 // Clear any textures used by the current program.
1041 bool ClearUnclearedTextures();
1042
1043 // Clear any uncleared level in texture.
1044 // Returns false if there was a generated GL error.
[email protected]02965c22013-03-09 02:40:071045 bool ClearTexture(Texture* texture);
[email protected]0d6bfdc2011-11-02 01:32:201046
1047 // Clears any uncleared attachments attached to the given frame buffer.
1048 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061049 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281050
[email protected]0d6bfdc2011-11-02 01:32:201051 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:001052 virtual bool ClearLevel(unsigned service_id,
1053 unsigned bind_target,
1054 unsigned target,
1055 int level,
1056 unsigned format,
1057 unsigned type,
1058 int width,
1059 int height,
1060 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:201061
[email protected]c007aa02010-09-02 22:22:401062 // Restore all GL state that affects clearing.
1063 void RestoreClearState();
1064
[email protected]3a2e7c7b2010-08-06 01:12:281065 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461066 // Returns: true if glEnable/glDisable should actually be called.
1067 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281068
[email protected]0d6bfdc2011-11-02 01:32:201069 // Check that the currently bound framebuffers are valid.
1070 // Generates GL error if not.
1071 bool CheckBoundFramebuffersValid(const char* func_name);
1072
1073 // Check if a framebuffer meets our requirements.
1074 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351075 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201076 GLenum target,
1077 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271078
[email protected]939e7362010-05-13 20:49:101079 // Checks if the current program exists and is valid. If not generates the
1080 // appropriate GL error. Returns true if the current program is in a usable
1081 // state.
1082 bool CheckCurrentProgram(const char* function_name);
1083
1084 // Checks if the current program exists and is valid and that location is not
1085 // -1. If the current program is not valid generates the appropriate GL
1086 // error. Returns true if the current program is in a usable state and
1087 // location is not -1.
1088 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1089
1090 // Gets the type of a uniform for a location in the current program. Sets GL
1091 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361092 // program is valid and the location exists. Adjusts count so it
1093 // does not overflow the uniform.
1094 bool PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:121095 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:521096 const BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:121097 GLint* real_location, GLenum* type, GLsizei* count);
[email protected]939e7362010-05-13 20:49:101098
[email protected]b177ae22011-11-01 03:29:111099 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021100 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111101
[email protected]b273e432010-04-12 17:23:581102 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1103 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1104
[email protected]ac77603c72013-03-08 13:52:061105 // Helper for glGetVertexAttrib
1106 void GetVertexAttribHelper(
1107 const VertexAttrib* attrib, GLenum pname, GLint* param);
1108
[email protected]96449d2c2009-11-25 00:01:321109 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031110 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321111
1112 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031113 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321114
[email protected]3916c97e2010-02-25 03:20:501115 // Wrapper for glActiveTexture
1116 void DoActiveTexture(GLenum texture_unit);
1117
[email protected]ae51d192010-04-27 00:48:031118 // Wrapper for glAttachShader
1119 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1120
[email protected]96449d2c2009-11-25 00:01:321121 // Wrapper for glBindBuffer since we need to track the current targets.
1122 void DoBindBuffer(GLenum target, GLuint buffer);
1123
[email protected]86093972010-03-11 00:13:561124 // Wrapper for glBindFramebuffer since we need to track the current targets.
1125 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1126
1127 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1128 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1129
[email protected]a93bb842010-02-16 23:03:471130 // Wrapper for glBindTexture since we need to track the current targets.
1131 void DoBindTexture(GLenum target, GLuint texture);
1132
[email protected]944b62f32012-09-27 02:20:461133 // Wrapper for glBindVertexArrayOES
1134 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571135 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461136
[email protected]8e3e0662010-08-23 18:46:301137 // Wrapper for glBlitFramebufferEXT.
1138 void DoBlitFramebufferEXT(
1139 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1140 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1141 GLbitfield mask, GLenum filter);
1142
[email protected]36cef8ce2010-03-16 07:34:451143 // Wrapper for glBufferData.
[email protected]0c86dbf2010-03-05 08:14:111144 void DoBufferData(
1145 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
1146
[email protected]36cef8ce2010-03-16 07:34:451147 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111148 void DoBufferSubData(
1149 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1150
[email protected]36cef8ce2010-03-16 07:34:451151 // Wrapper for glCheckFramebufferStatus
1152 GLenum DoCheckFramebufferStatus(GLenum target);
1153
[email protected]3a03a8f2011-03-19 00:51:271154 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081155 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271156
[email protected]88a61bf2012-10-27 13:00:421157 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421158 void DoDepthRangef(GLclampf znear, GLclampf zfar);
1159 void DoHint(GLenum target, GLenum mode);
[email protected]b04e24c2013-01-08 18:35:251160 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281161
[email protected]45bf5152010-02-12 00:11:311162 // Wrapper for glCompileShader.
1163 void DoCompileShader(GLuint shader);
1164
[email protected]269200b12010-11-18 22:53:061165 // Helper for DeleteSharedIdsCHROMIUM commands.
1166 void DoDeleteSharedIdsCHROMIUM(
1167 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101168
[email protected]ae51d192010-04-27 00:48:031169 // Wrapper for glDetachShader
1170 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1171
[email protected]3a2e7c7b2010-08-06 01:12:281172 // Wrapper for glDisable
1173 void DoDisable(GLenum cap);
1174
[email protected]07f54fcc2009-12-22 02:46:301175 // Wrapper for glDisableVertexAttribArray.
1176 void DoDisableVertexAttribArray(GLuint index);
1177
[email protected]60f22d32012-12-12 00:31:581178 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1179 // attachments.
1180 void DoDiscardFramebufferEXT(GLenum target,
1181 GLsizei numAttachments,
1182 const GLenum* attachments);
1183
[email protected]3a2e7c7b2010-08-06 01:12:281184 // Wrapper for glEnable
1185 void DoEnable(GLenum cap);
1186
[email protected]07f54fcc2009-12-22 02:46:301187 // Wrapper for glEnableVertexAttribArray.
1188 void DoEnableVertexAttribArray(GLuint index);
1189
[email protected]882ba1e22012-03-08 19:02:531190 // Wrapper for glFinish.
1191 void DoFinish();
1192
1193 // Wrapper for glFlush.
1194 void DoFlush();
1195
[email protected]36cef8ce2010-03-16 07:34:451196 // Wrapper for glFramebufferRenderbufffer.
1197 void DoFramebufferRenderbuffer(
1198 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1199 GLuint renderbuffer);
1200
1201 // Wrapper for glFramebufferTexture2D.
1202 void DoFramebufferTexture2D(
1203 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1204 GLint level);
1205
[email protected]a93bb842010-02-16 23:03:471206 // Wrapper for glGenerateMipmap
1207 void DoGenerateMipmap(GLenum target);
1208
[email protected]269200b12010-11-18 22:53:061209 // Helper for GenSharedIdsCHROMIUM commands.
1210 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101211 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1212
[email protected]b273e432010-04-12 17:23:581213 // Wrapper for DoGetBooleanv.
1214 void DoGetBooleanv(GLenum pname, GLboolean* params);
1215
1216 // Wrapper for DoGetFloatv.
1217 void DoGetFloatv(GLenum pname, GLfloat* params);
1218
[email protected]36cef8ce2010-03-16 07:34:451219 // Wrapper for glGetFramebufferAttachmentParameteriv.
1220 void DoGetFramebufferAttachmentParameteriv(
1221 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1222
[email protected]a0c3e972010-04-21 00:49:131223 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581224 void DoGetIntegerv(GLenum pname, GLint* params);
1225
[email protected]29a9eb52010-04-13 09:04:231226 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061227 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231228 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1229
[email protected]17cfbe0e2013-03-07 01:26:081230 // Wrapper for glGetBufferParameteriv.
1231 void DoGetBufferParameteriv(
1232 GLenum target, GLenum pname, GLint* params);
1233
[email protected]a0c3e972010-04-21 00:49:131234 // Wrapper for glGetProgramiv.
1235 void DoGetProgramiv(
1236 GLuint program_id, GLenum pname, GLint* params);
1237
[email protected]36cef8ce2010-03-16 07:34:451238 // Wrapper for glRenderbufferParameteriv.
1239 void DoGetRenderbufferParameteriv(
1240 GLenum target, GLenum pname, GLint* params);
1241
[email protected]ddd968b82010-03-02 00:44:291242 // Wrapper for glGetShaderiv
1243 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1244
[email protected]b1122982010-05-17 23:04:241245 // Wrappers for glGetVertexAttrib.
1246 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1247 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1248
[email protected]1958e0e2010-04-22 05:17:151249 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241250 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151251 bool DoIsBuffer(GLuint client_id);
1252 bool DoIsFramebuffer(GLuint client_id);
1253 bool DoIsProgram(GLuint client_id);
1254 bool DoIsRenderbuffer(GLuint client_id);
1255 bool DoIsShader(GLuint client_id);
1256 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461257 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151258
[email protected]07f54fcc2009-12-22 02:46:301259 // Wrapper for glLinkProgram
1260 void DoLinkProgram(GLuint program);
1261
[email protected]269200b12010-11-18 22:53:061262 // Helper for RegisterSharedIdsCHROMIUM.
1263 void DoRegisterSharedIdsCHROMIUM(
1264 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101265
[email protected]36cef8ce2010-03-16 07:34:451266 // Wrapper for glRenderbufferStorage.
1267 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031268 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451269
[email protected]8e3e0662010-08-23 18:46:301270 // Wrapper for glRenderbufferStorageMultisampleEXT.
1271 void DoRenderbufferStorageMultisample(
1272 GLenum target, GLsizei samples, GLenum internalformat,
1273 GLsizei width, GLsizei height);
1274
[email protected]b273e432010-04-12 17:23:581275 // Wrapper for glReleaseShaderCompiler.
1276 void DoReleaseShaderCompiler() { }
1277
[email protected]3916c97e2010-02-25 03:20:501278 // Wrappers for glTexParameter functions.
1279 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1280 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1281 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1282 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1283
1284 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1285 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121286 void DoUniform1i(GLint fake_location, GLint v0);
1287 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1288 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1289 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1290 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101291
1292 // Wrappers for glUniformfv because some drivers don't correctly accept
1293 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121294 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1295 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1296 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1297 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501298
[email protected]43c2f1f2011-03-25 18:35:361299 void DoUniformMatrix2fv(
[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 DoUniformMatrix3fv(
[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 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121306 GLint fake_location, GLsizei count, GLboolean transpose,
1307 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361308
[email protected]af6380962012-11-29 23:24:131309 bool SetVertexAttribValue(
1310 const char* function_name, GLuint index, const GLfloat* value);
1311
[email protected]b1122982010-05-17 23:04:241312 // Wrappers for glVertexAttrib??
1313 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1314 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1315 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1316 void DoVertexAttrib4f(
1317 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1318 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1319 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1320 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1321 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1322
[email protected]43410e92012-04-20 17:06:281323 // Wrapper for glViewport
1324 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1325
[email protected]07f54fcc2009-12-22 02:46:301326 // Wrapper for glUseProgram
1327 void DoUseProgram(GLuint program);
1328
[email protected]ae51d192010-04-27 00:48:031329 // Wrapper for glValidateProgram.
1330 void DoValidateProgram(GLuint program_client_id);
1331
[email protected]d2a0e1a2012-08-12 02:25:011332 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1333 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1334 void DoPopGroupMarkerEXT(void);
1335
[email protected]4e8a5b122010-05-08 22:00:101336 // Gets the number of values that will be returned by glGetXXX. Returns
1337 // false if pname is unknown.
1338 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1339
[email protected]07f54fcc2009-12-22 02:46:301340 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431341 bool IsDrawValid(
1342 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301343
[email protected]c13e1da62011-09-09 21:48:301344 // Returns true if successful, simulated will be true if attrib0 was
1345 // simulated.
[email protected]c6aef902012-02-14 03:31:421346 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431347 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]43410e92012-04-20 17:06:281348 void RestoreStateForAttrib(GLuint attrib);
[email protected]b1122982010-05-17 23:04:241349
[email protected]ef526492010-06-02 23:12:251350 // Returns true if textures were set.
1351 bool SetBlackTextureForNonRenderableTextures();
[email protected]3916c97e2010-02-25 03:20:501352 void RestoreStateForNonRenderableTextures();
1353
[email protected]8fbedc02010-11-18 18:43:401354 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421355 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431356 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421357 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401358 void RestoreStateForSimulatedFixedAttribs();
1359
[email protected]c6aef902012-02-14 03:31:421360 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1361 // cases (primcount is 0 for non-instanced).
1362 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431363 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421364 bool instanced, GLenum mode, GLint first, GLsizei count,
1365 GLsizei primcount);
1366 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431367 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421368 bool instanced, GLenum mode, GLsizei count, GLenum type,
1369 int32 offset, GLsizei primcount);
1370
[email protected]07f54fcc2009-12-22 02:46:301371 // Gets the buffer id for a given target.
[email protected]16ccec12013-02-28 03:40:211372 Buffer* GetBufferInfoForTarget(GLenum target) {
[email protected]07f54fcc2009-12-22 02:46:301373 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER);
[email protected]944b62f32012-09-27 02:20:461374 if (target == GL_ARRAY_BUFFER) {
[email protected]e259eb412012-10-13 05:47:241375 return state_.bound_array_buffer;
[email protected]944b62f32012-09-27 02:20:461376 } else {
[email protected]e259eb412012-10-13 05:47:241377 return state_.vertex_attrib_manager->element_array_buffer();
[email protected]944b62f32012-09-27 02:20:461378 }
[email protected]07f54fcc2009-12-22 02:46:301379 }
1380
[email protected]a93bb842010-02-16 23:03:471381 // Gets the texture id for a given target.
[email protected]370eaf12013-05-18 09:19:491382 TextureRef* GetTextureInfoForTarget(GLenum target) {
[email protected]e259eb412012-10-13 05:47:241383 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]370eaf12013-05-18 09:19:491384 TextureRef* texture = NULL;
[email protected]a93bb842010-02-16 23:03:471385 switch (target) {
1386 case GL_TEXTURE_2D:
[email protected]02965c22013-03-09 02:40:071387 texture = unit.bound_texture_2d;
[email protected]3916c97e2010-02-25 03:20:501388 break;
[email protected]a93bb842010-02-16 23:03:471389 case GL_TEXTURE_CUBE_MAP:
1390 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1391 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1392 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1393 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1394 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1395 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
[email protected]02965c22013-03-09 02:40:071396 texture = unit.bound_texture_cube_map;
[email protected]3916c97e2010-02-25 03:20:501397 break;
[email protected]61eeb33f2011-07-26 15:30:311398 case GL_TEXTURE_EXTERNAL_OES:
[email protected]02965c22013-03-09 02:40:071399 texture = unit.bound_texture_external_oes;
[email protected]61eeb33f2011-07-26 15:30:311400 break;
[email protected]e51bdf32011-11-23 22:21:461401 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]02965c22013-03-09 02:40:071402 texture = unit.bound_texture_rectangle_arb;
[email protected]e51bdf32011-11-23 22:21:461403 break;
[email protected]a93bb842010-02-16 23:03:471404 default:
1405 NOTREACHED();
[email protected]3916c97e2010-02-25 03:20:501406 return NULL;
[email protected]a93bb842010-02-16 23:03:471407 }
[email protected]02965c22013-03-09 02:40:071408 return texture;
[email protected]a93bb842010-02-16 23:03:471409 }
1410
[email protected]370eaf12013-05-18 09:19:491411 TextureRef* GetTextureInfoForTargetUnlessDefault(
[email protected]09d50362012-10-18 20:54:371412 GLenum target) {
[email protected]370eaf12013-05-18 09:19:491413 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:071414 if (!texture)
[email protected]09d50362012-10-18 20:54:371415 return NULL;
[email protected]02965c22013-03-09 02:40:071416 if (texture == texture_manager()->GetDefaultTextureInfo(target))
[email protected]09d50362012-10-18 20:54:371417 return NULL;
[email protected]02965c22013-03-09 02:40:071418 return texture;
[email protected]09d50362012-10-18 20:54:371419 }
1420
[email protected]61eeb33f2011-07-26 15:30:311421 GLenum GetBindTargetForSamplerType(GLenum type) {
1422 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461423 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1424 switch (type) {
1425 case GL_SAMPLER_2D:
1426 return GL_TEXTURE_2D;
1427 case GL_SAMPLER_CUBE:
1428 return GL_TEXTURE_CUBE_MAP;
1429 case GL_SAMPLER_EXTERNAL_OES:
1430 return GL_TEXTURE_EXTERNAL_OES;
1431 case GL_SAMPLER_2D_RECT_ARB:
1432 return GL_TEXTURE_RECTANGLE_ARB;
1433 }
1434
1435 NOTREACHED();
1436 return 0;
[email protected]61eeb33f2011-07-26 15:30:311437 }
1438
[email protected]8e3e0662010-08-23 18:46:301439 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061440 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1441 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301442 switch (target) {
1443 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451444 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]4d8f0dd2013-03-09 14:37:061445 framebuffer = state_.bound_draw_framebuffer;
[email protected]8e3e0662010-08-23 18:46:301446 break;
[email protected]ebfb73c2012-08-15 02:37:451447 case GL_READ_FRAMEBUFFER_EXT:
[email protected]4d8f0dd2013-03-09 14:37:061448 framebuffer = state_.bound_read_framebuffer;
[email protected]8e3e0662010-08-23 18:46:301449 break;
1450 default:
1451 NOTREACHED();
1452 break;
1453 }
[email protected]4d8f0dd2013-03-09 14:37:061454 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301455 }
1456
[email protected]ed9f9cd2013-02-27 21:12:351457 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201458 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271459 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201460 switch (target) {
1461 case GL_RENDERBUFFER:
[email protected]ee2a79c32013-03-10 03:50:271462 renderbuffer = state_.bound_renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201463 break;
1464 default:
1465 NOTREACHED();
1466 break;
1467 }
[email protected]ee2a79c32013-03-10 03:50:271468 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201469 }
1470
[email protected]f7b85372010-02-03 01:11:371471 // Validates the program and location for a glGetUniform call and returns
1472 // a SizeResult setup to receive the result. Returns true if glGetUniform
1473 // should be called.
1474 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121475 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371476 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121477 error::Error* error, GLint* real_location, GLuint* service_id,
1478 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371479
[email protected]1078f912011-12-23 13:12:141480 // Computes the estimated memory used for the backbuffer and passes it to
1481 // the tracing system.
[email protected]260ddc4e2012-06-28 00:01:531482 size_t GetBackbufferMemoryTotal();
[email protected]1078f912011-12-23 13:12:141483
[email protected]a10b4a02012-11-26 23:09:501484 virtual bool WasContextLost() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091485 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431486
[email protected]e51bdf32011-11-23 22:21:461487#if defined(OS_MACOSX)
1488 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1489#endif
1490
[email protected]81375742012-06-08 00:04:001491 // Validates the combination of texture parameters. For example validates that
1492 // for a given format the specific type, level and targets are valid.
1493 // Synthesizes the correct GL error if invalid. Returns true if valid.
1494 bool ValidateTextureParameters(
1495 const char* function_name,
1496 GLenum target, GLenum format, GLenum type, GLint level);
1497
[email protected]ad84a3a2012-06-08 21:42:431498 bool ValidateCompressedTexDimensions(
1499 const char* function_name,
1500 GLint level, GLsizei width, GLsizei height, GLenum format);
1501 bool ValidateCompressedTexFuncData(
1502 const char* function_name,
1503 GLsizei width, GLsizei height, GLenum format, size_t size);
1504 bool ValidateCompressedTexSubDimensions(
1505 const char* function_name,
1506 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1507 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351508 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431509
[email protected]ab09b612013-03-11 22:11:511510 void RenderWarning(const char* filename, int line, const std::string& msg);
1511 void PerformanceWarning(
1512 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011513
[email protected]62e155e2012-10-23 22:43:151514 const FeatureInfo::FeatureFlags& features() const {
1515 return feature_info_->feature_flags();
1516 }
1517
1518 const FeatureInfo::Workarounds& workarounds() const {
1519 return feature_info_->workarounds();
1520 }
1521
[email protected]a7266a92012-06-28 02:11:081522 bool ShouldDeferDraws() {
1523 return !offscreen_target_frame_buffer_.get() &&
[email protected]e259eb412012-10-13 05:47:241524 state_.bound_draw_framebuffer == NULL &&
[email protected]a7266a92012-06-28 02:11:081525 surface_->DeferDraws();
1526 }
1527
[email protected]09e17272012-11-30 10:30:441528 bool ShouldDeferReads() {
1529 return !offscreen_target_frame_buffer_.get() &&
1530 state_.bound_read_framebuffer == NULL &&
1531 surface_->DeferDraws();
1532 }
1533
[email protected]df37b9932013-03-08 05:21:421534 void ForceCompileShaderIfPending(Shader* shader);
[email protected]c447acd2012-07-23 23:48:411535
[email protected]96449d2c2009-11-25 00:01:321536 // Generate a member function prototype for each command in an automated and
1537 // typesafe way.
1538 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141539 Error Handle ## name( \
[email protected]ed9f9cd2013-02-27 21:12:351540 uint32 immediate_data_size, \
1541 const cmds::name& args); \
[email protected]96449d2c2009-11-25 00:01:321542
1543 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1544
1545 #undef GLES2_CMD_OP
1546
[email protected]2f2d7042010-04-14 21:45:581547 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381548 scoped_refptr<gfx::GLSurface> surface_;
1549 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021550
[email protected]a3ded6d2010-10-19 06:44:391551 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351552 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391553
[email protected]1d82e822013-04-10 21:32:321554 DebugMarkerManager debug_marker_manager_;
1555 Logger logger_;
1556
[email protected]e259eb412012-10-13 05:47:241557 // All the state for this context.
1558 ContextState state_;
1559
[email protected]6217d392010-03-25 22:08:351560 // A parent decoder can access this decoders saved offscreen frame buffer.
1561 // The parent pointer is reset if the parent is destroyed.
1562 base::WeakPtr<GLES2DecoderImpl> parent_;
1563
[email protected]34ff8b0c2010-10-01 20:06:021564 // Current width and height of the offscreen frame buffer.
1565 gfx::Size offscreen_size_;
1566
[email protected]96449d2c2009-11-25 00:01:321567 // Util to help with GL.
1568 GLES2Util util_;
1569
[email protected]43410e92012-04-20 17:06:281570 // unpack flip y as last set by glPixelStorei
1571 bool unpack_flip_y_;
1572
[email protected]6c75c712012-06-19 15:43:171573 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281574 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171575 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281576
[email protected]944b62f32012-09-27 02:20:461577 // Default vertex attribs manager, used when no VAOs are bound.
[email protected]ed9f9cd2013-02-27 21:12:351578 scoped_refptr<VertexAttribManager> default_vertex_attrib_manager_;
[email protected]07f54fcc2009-12-22 02:46:301579
[email protected]b1122982010-05-17 23:04:241580 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1581 GLuint attrib_0_buffer_id_;
1582
1583 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131584 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241585
[email protected]fc753442011-02-04 19:49:491586 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1587 bool attrib_0_buffer_matches_value_;
1588
[email protected]b1122982010-05-17 23:04:241589 // The size of attrib 0.
1590 GLsizei attrib_0_size_;
1591
[email protected]8fbedc02010-11-18 18:43:401592 // The buffer used to simulate GL_FIXED attribs.
1593 GLuint fixed_attrib_buffer_id_;
1594
1595 // The size of fiixed attrib buffer.
1596 GLsizei fixed_attrib_buffer_size_;
1597
[email protected]3a2e7c7b2010-08-06 01:12:281598 // state saved for clearing so we can clear render buffers and then
1599 // restore to these values.
[email protected]88a61bf2012-10-27 13:00:421600 bool clear_state_dirty_;
[email protected]3a2e7c7b2010-08-06 01:12:281601
[email protected]b9363b22010-06-09 22:06:151602 // The offscreen frame buffer that the client renders to. With EGL, the
1603 // depth and stencil buffers are separate. With regular GL there is a single
1604 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1605 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351606 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1607 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1608 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1609 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1610 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021611 GLenum offscreen_target_color_format_;
1612 GLenum offscreen_target_depth_format_;
1613 GLenum offscreen_target_stencil_format_;
1614 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561615 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351616
[email protected]de26b3c2011-08-03 21:54:271617 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351618 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1619 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491620 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351621 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271622
1623 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351624 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1625 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051626 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351627
[email protected]882ba1e22012-03-08 19:02:531628 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531629
[email protected]944b62f32012-09-27 02:20:461630 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1631
[email protected]729c0b42013-05-26 02:05:071632 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001633
[email protected]840a7e462013-02-27 01:29:511634 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481635
[email protected]e3932abb2013-03-13 00:01:371636 ShaderCacheCallback shader_cache_callback_;
1637
[email protected]b0af4f52011-09-28 22:04:421638 StreamTextureManager* stream_texture_manager_;
[email protected]85a4ac22013-05-31 01:58:471639 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421640
[email protected]32fe9aa2011-01-21 23:47:131641 // The format of the back buffer_
1642 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461643 bool back_buffer_has_depth_;
1644 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131645
[email protected]60f22d32012-12-12 00:31:581646 // Backbuffer attachments that are currently undefined.
1647 uint32 backbuffer_needs_clear_bits_;
1648
[email protected]473c01ccb2011-06-07 01:33:301649 bool teximage2d_faster_than_texsubimage2d_;
[email protected]473c01ccb2011-06-07 01:33:301650
[email protected]a3a93e7b2010-08-28 00:48:561651 // The current decoder error.
1652 error::Error current_decoder_error_;
1653
[email protected]b1d2dcb2010-05-17 19:24:181654 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041655 scoped_refptr<ShaderTranslator> vertex_translator_;
1656 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181657
[email protected]e82fb792011-09-22 00:33:291658 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411659
[email protected]915a59a12010-09-30 21:29:111660 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051661 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351662 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051663
[email protected]b493ee622011-04-13 23:52:001664 // This indicates all the following texSubImage2D calls that are part of the
1665 // failed texImage2D call should be ignored.
1666 bool tex_image_2d_failed_;
1667
[email protected]65225772011-05-12 21:10:241668 int frame_number_;
1669
[email protected]706b69f2012-07-27 04:59:301670 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431671 GLenum reset_status_;
1672
[email protected]f0d74742011-10-03 16:31:041673 // These flags are used to override the state of the shared feature_info_
1674 // member. Because the same FeatureInfo instance may be shared among many
1675 // contexts, the assumptions on the availablity of extensions in WebGL
1676 // contexts may be broken. These flags override the shared state to preserve
1677 // WebGL semantics.
1678 bool force_webgl_glsl_validation_;
1679 bool derivatives_explicitly_enabled_;
1680
[email protected]062c38b2012-01-18 03:25:101681 bool compile_shader_always_succeeds_;
1682
[email protected]cae20172012-12-07 00:06:191683 // Log extra info.
1684 bool service_logging_;
1685
[email protected]e51bdf32011-11-23 22:21:461686#if defined(OS_MACOSX)
1687 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap;
1688 TextureToIOSurfaceMap texture_to_io_surface_map_;
1689#endif
1690
[email protected]c826d732012-02-09 04:40:261691 typedef std::vector<GLES2DecoderImpl*> ChildList;
1692 ChildList children_;
1693
[email protected]43410e92012-04-20 17:06:281694 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1695
[email protected]1868a342012-11-07 15:56:021696 // Cached values of the currently assigned viewport dimensions.
1697 GLsizei viewport_max_width_;
1698 GLsizei viewport_max_height_;
1699
[email protected]63b465922012-09-06 02:04:521700 // Command buffer stats.
1701 int texture_upload_count_;
1702 base::TimeDelta total_texture_upload_time_;
1703 base::TimeDelta total_processing_commands_time_;
1704
[email protected]fb97b662013-02-20 23:02:141705 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]94307712012-11-16 23:26:111706
[email protected]96449d2c2009-11-25 00:01:321707 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1708};
1709
[email protected]ab09b612013-03-11 22:11:511710ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
1711 const char* function_name, GLES2DecoderImpl* decoder)
1712 : function_name_(function_name),
1713 decoder_(decoder) {
[email protected]d3eba342013-04-18 21:11:501714 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(decoder_->GetErrorState(),
1715 function_name_);
[email protected]6217d392010-03-25 22:08:351716}
1717
1718ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]d3eba342013-04-18 21:11:501719 ERRORSTATE_CLEAR_REAL_GL_ERRORS(decoder_->GetErrorState(), function_name_);
[email protected]6217d392010-03-25 22:08:351720}
1721
1722ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder,
1723 GLuint id)
1724 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511725 ScopedGLErrorSuppressor suppressor(
1726 "ScopedTexture2DBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351727
1728 // TODO(apatrick): Check if there are any other states that need to be reset
1729 // before binding a new texture.
1730 glActiveTexture(GL_TEXTURE0);
1731 glBindTexture(GL_TEXTURE_2D, id);
1732}
1733
1734ScopedTexture2DBinder::~ScopedTexture2DBinder() {
[email protected]ab09b612013-03-11 22:11:511735 ScopedGLErrorSuppressor suppressor(
1736 "ScopedTexture2DBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301737 decoder_->RestoreCurrentTexture2DBindings();
[email protected]6217d392010-03-25 22:08:351738}
1739
1740ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder,
1741 GLuint id)
1742 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511743 ScopedGLErrorSuppressor suppressor(
1744 "ScopedRenderBufferBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351745 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1746}
1747
1748ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511749 ScopedGLErrorSuppressor suppressor(
1750 "ScopedRenderBufferBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301751 decoder_->RestoreCurrentRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351752}
1753
1754ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1755 GLuint id)
1756 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511757 ScopedGLErrorSuppressor suppressor(
1758 "ScopedFrameBufferBinder::ctor", decoder_);
[email protected]6217d392010-03-25 22:08:351759 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451760 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351761}
1762
1763ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511764 ScopedGLErrorSuppressor suppressor(
1765 "ScopedFrameBufferBinder::dtor", decoder_);
[email protected]8e3e0662010-08-23 18:46:301766 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351767}
1768
[email protected]34ff8b0c2010-10-01 20:06:021769ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271770 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521771 : decoder_(decoder) {
[email protected]34ff8b0c2010-10-01 20:06:021772 resolve_and_bind_ = (decoder_->offscreen_target_frame_buffer_.get() &&
1773 decoder_->IsOffscreenBufferMultisampled() &&
[email protected]e259eb412012-10-13 05:47:241774 (!decoder_->state_.bound_read_framebuffer.get() ||
[email protected]c0701082011-04-20 00:34:521775 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021776 if (!resolve_and_bind_)
1777 return;
1778
[email protected]ab09b612013-03-11 22:11:511779 ScopedGLErrorSuppressor suppressor(
1780 "ScopedResolvedFrameBufferBinder::ctor", decoder_);
[email protected]34ff8b0c2010-10-01 20:06:021781 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1782 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271783 GLuint targetid;
1784 if (internal) {
1785 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1786 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351787 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271788 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351789 decoder_->offscreen_resolved_color_texture_.reset(
1790 new BackTexture(decoder_));
[email protected]de26b3c2011-08-03 21:54:271791 decoder_->offscreen_resolved_color_texture_->Create();
1792
1793 DCHECK(decoder_->offscreen_saved_color_format_);
1794 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091795 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1796 false);
[email protected]de26b3c2011-08-03 21:54:271797 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1798 decoder_->offscreen_resolved_color_texture_.get());
1799 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1800 GL_FRAMEBUFFER_COMPLETE) {
1801 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1802 << "because offscreen resolved FBO was incomplete.";
1803 return;
1804 }
1805 }
1806 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1807 } else {
1808 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1809 }
1810 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021811 const int width = decoder_->offscreen_size_.width();
1812 const int height = decoder_->offscreen_size_.height();
[email protected]8c3e68782010-10-27 16:41:181813 glDisable(GL_SCISSOR_TEST);
[email protected]57edfdad2012-02-07 04:57:151814 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021815 glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height,
1816 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1817 } else {
1818 glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height,
1819 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1820 }
[email protected]de26b3c2011-08-03 21:54:271821 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021822}
1823
1824ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1825 if (!resolve_and_bind_)
1826 return;
1827
[email protected]ab09b612013-03-11 22:11:511828 ScopedGLErrorSuppressor suppressor(
1829 "ScopedResolvedFrameBufferBinder::dtor", decoder_);
[email protected]34ff8b0c2010-10-01 20:06:021830 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:221831 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]8c3e68782010-10-27 16:41:181832 glEnable(GL_SCISSOR_TEST);
1833 }
[email protected]34ff8b0c2010-10-01 20:06:021834}
1835
[email protected]63b465922012-09-06 02:04:521836ScopedTextureUploadTimer::ScopedTextureUploadTimer(GLES2DecoderImpl* decoder)
1837 : decoder_(decoder),
1838 begin_time_(base::TimeTicks::HighResNow()) {
1839}
1840
1841ScopedTextureUploadTimer::~ScopedTextureUploadTimer() {
1842 decoder_->texture_upload_count_++;
1843 decoder_->total_texture_upload_time_ +=
1844 base::TimeTicks::HighResNow() - begin_time_;
1845}
1846
[email protected]ed9f9cd2013-02-27 21:12:351847BackTexture::BackTexture(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:351848 : decoder_(decoder),
[email protected]7989c9e2013-01-23 06:39:261849 memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged),
[email protected]68e81a4a62012-12-13 01:16:481850 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251851 id_(0) {
[email protected]6217d392010-03-25 22:08:351852}
1853
[email protected]ed9f9cd2013-02-27 21:12:351854BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:351855 // This does not destroy the render texture because that would require that
1856 // the associated GL context was current. Just check that it was explicitly
1857 // destroyed.
1858 DCHECK_EQ(id_, 0u);
1859}
1860
[email protected]ed9f9cd2013-02-27 21:12:351861void BackTexture::Create() {
[email protected]ab09b612013-03-11 22:11:511862 ScopedGLErrorSuppressor suppressor("BackTexture::Create", decoder_);
[email protected]6217d392010-03-25 22:08:351863 Destroy();
1864 glGenTextures(1, &id_);
[email protected]3a4d0c52011-06-29 23:11:581865 ScopedTexture2DBinder binder(decoder_, id_);
1866 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1867 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1868 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1869 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:161870
1871 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
1872 // never called on an offscreen context, no data will ever be uploaded to the
1873 // saved offscreen color texture (it is deferred until to when SwapBuffers
1874 // is called). My idea is that some nvidia drivers might have a bug where
1875 // deleting a texture that has never been populated might cause a
1876 // crash.
1877 glTexImage2D(
1878 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:481879
1880 bytes_allocated_ = 16u * 16u * 4u;
1881 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:351882}
1883
[email protected]ed9f9cd2013-02-27 21:12:351884bool BackTexture::AllocateStorage(
1885 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:351886 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:511887 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage", decoder_);
[email protected]6217d392010-03-25 22:08:351888 ScopedTexture2DBinder binder(decoder_, id_);
[email protected]678a73f2012-12-19 19:22:091889 uint32 image_size = 0;
1890 GLES2Util::ComputeImageDataSizes(
1891 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
1892 NULL, NULL);
1893
[email protected]7989c9e2013-01-23 06:39:261894 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
1895 return false;
1896 }
1897
[email protected]40d90a22013-04-09 03:39:551898 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:091899 if (zero) {
1900 zero_data.reset(new char[image_size]);
1901 memset(zero_data.get(), 0, image_size);
1902 }
[email protected]6217d392010-03-25 22:08:351903
[email protected]8f1d2aa2013-05-10 23:45:381904 glTexImage2D(GL_TEXTURE_2D,
1905 0, // mip level
1906 format,
1907 size.width(),
1908 size.height(),
1909 0, // border
1910 format,
1911 GL_UNSIGNED_BYTE,
1912 zero_data.get());
[email protected]6217d392010-03-25 22:08:351913
[email protected]d37231fa2010-04-09 21:16:021914 size_ = size;
1915
[email protected]1078f912011-12-23 13:12:141916 bool success = glGetError() == GL_NO_ERROR;
1917 if (success) {
[email protected]68e81a4a62012-12-13 01:16:481918 memory_tracker_.TrackMemFree(bytes_allocated_);
1919 bytes_allocated_ = image_size;
1920 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:141921 }
1922 return success;
[email protected]6217d392010-03-25 22:08:351923}
1924
[email protected]ed9f9cd2013-02-27 21:12:351925void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:351926 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:511927 ScopedGLErrorSuppressor suppressor("BackTexture::Copy", decoder_);
[email protected]6217d392010-03-25 22:08:351928 ScopedTexture2DBinder binder(decoder_, id_);
1929 glCopyTexImage2D(GL_TEXTURE_2D,
1930 0, // level
[email protected]3a4d0c52011-06-29 23:11:581931 format,
[email protected]6217d392010-03-25 22:08:351932 0, 0,
1933 size.width(),
1934 size.height(),
1935 0); // border
1936}
1937
[email protected]ed9f9cd2013-02-27 21:12:351938void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:351939 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:511940 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:351941 glDeleteTextures(1, &id_);
1942 id_ = 0;
1943 }
[email protected]68e81a4a62012-12-13 01:16:481944 memory_tracker_.TrackMemFree(bytes_allocated_);
1945 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:351946}
1947
[email protected]ed9f9cd2013-02-27 21:12:351948void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:051949 id_ = 0;
1950}
1951
[email protected]ed9f9cd2013-02-27 21:12:351952BackRenderbuffer::BackRenderbuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:351953 : decoder_(decoder),
[email protected]7989c9e2013-01-23 06:39:261954 memory_tracker_(decoder->memory_tracker(), MemoryTracker::kUnmanaged),
[email protected]68e81a4a62012-12-13 01:16:481955 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251956 id_(0) {
[email protected]6217d392010-03-25 22:08:351957}
1958
[email protected]ed9f9cd2013-02-27 21:12:351959BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:351960 // This does not destroy the render buffer because that would require that
1961 // the associated GL context was current. Just check that it was explicitly
1962 // destroyed.
1963 DCHECK_EQ(id_, 0u);
1964}
1965
[email protected]ed9f9cd2013-02-27 21:12:351966void BackRenderbuffer::Create() {
[email protected]ab09b612013-03-11 22:11:511967 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create", decoder_);
[email protected]6217d392010-03-25 22:08:351968 Destroy();
1969 glGenRenderbuffersEXT(1, &id_);
1970}
1971
[email protected]ed9f9cd2013-02-27 21:12:351972bool BackRenderbuffer::AllocateStorage(const gfx::Size& size, GLenum format,
1973 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:511974 ScopedGLErrorSuppressor suppressor(
1975 "BackRenderbuffer::AllocateStorage", decoder_);
[email protected]6217d392010-03-25 22:08:351976 ScopedRenderBufferBinder binder(decoder_, id_);
[email protected]7989c9e2013-01-23 06:39:261977
1978 uint32 estimated_size = 0;
1979 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
1980 size.width(), size.height(), samples, format, &estimated_size)) {
1981 return false;
1982 }
1983
1984 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
1985 return false;
1986 }
1987
[email protected]34ff8b0c2010-10-01 20:06:021988 if (samples <= 1) {
1989 glRenderbufferStorageEXT(GL_RENDERBUFFER,
1990 format,
1991 size.width(),
1992 size.height());
1993 } else {
[email protected]57edfdad2012-02-07 04:57:151994 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021995 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER,
1996 samples,
1997 format,
1998 size.width(),
1999 size.height());
2000 } else {
2001 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
2002 samples,
2003 format,
2004 size.width(),
2005 size.height());
2006 }
2007 }
[email protected]1078f912011-12-23 13:12:142008 bool success = glGetError() == GL_NO_ERROR;
2009 if (success) {
[email protected]68e81a4a62012-12-13 01:16:482010 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262011 bytes_allocated_ = estimated_size;
[email protected]68e81a4a62012-12-13 01:16:482012 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142013 }
2014 return success;
[email protected]6217d392010-03-25 22:08:352015}
2016
[email protected]ed9f9cd2013-02-27 21:12:352017void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352018 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:512019 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:352020 glDeleteRenderbuffersEXT(1, &id_);
2021 id_ = 0;
2022 }
[email protected]68e81a4a62012-12-13 01:16:482023 memory_tracker_.TrackMemFree(bytes_allocated_);
2024 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352025}
2026
[email protected]ed9f9cd2013-02-27 21:12:352027void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052028 id_ = 0;
2029}
2030
[email protected]ed9f9cd2013-02-27 21:12:352031BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352032 : decoder_(decoder),
2033 id_(0) {
2034}
2035
[email protected]ed9f9cd2013-02-27 21:12:352036BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352037 // This does not destroy the frame buffer because that would require that
2038 // the associated GL context was current. Just check that it was explicitly
2039 // destroyed.
2040 DCHECK_EQ(id_, 0u);
2041}
2042
[email protected]ed9f9cd2013-02-27 21:12:352043void BackFramebuffer::Create() {
[email protected]ab09b612013-03-11 22:11:512044 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create", decoder_);
[email protected]6217d392010-03-25 22:08:352045 Destroy();
2046 glGenFramebuffersEXT(1, &id_);
2047}
2048
[email protected]ed9f9cd2013-02-27 21:12:352049void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352050 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512051 ScopedGLErrorSuppressor suppressor(
2052 "BackFramebuffer::AttachRenderTexture", decoder_);
[email protected]6217d392010-03-25 22:08:352053 ScopedFrameBufferBinder binder(decoder_, id_);
2054 GLuint attach_id = texture ? texture->id() : 0;
2055 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2056 GL_COLOR_ATTACHMENT0,
2057 GL_TEXTURE_2D,
2058 attach_id,
2059 0);
2060}
2061
[email protected]ed9f9cd2013-02-27 21:12:352062void BackFramebuffer::AttachRenderBuffer(GLenum target,
2063 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352064 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512065 ScopedGLErrorSuppressor suppressor(
2066 "BackFramebuffer::AttachRenderBuffer", decoder_);
[email protected]6217d392010-03-25 22:08:352067 ScopedFrameBufferBinder binder(decoder_, id_);
2068 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2069 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152070 target,
[email protected]6217d392010-03-25 22:08:352071 GL_RENDERBUFFER,
2072 attach_id);
2073}
2074
[email protected]ed9f9cd2013-02-27 21:12:352075void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352076 if (id_ != 0) {
[email protected]ab09b612013-03-11 22:11:512077 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy", decoder_);
[email protected]6217d392010-03-25 22:08:352078 glDeleteFramebuffersEXT(1, &id_);
2079 id_ = 0;
2080 }
2081}
2082
[email protected]ed9f9cd2013-02-27 21:12:352083void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052084 id_ = 0;
2085}
2086
[email protected]ed9f9cd2013-02-27 21:12:352087GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352088 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512089 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus", decoder_);
[email protected]6217d392010-03-25 22:08:352090 ScopedFrameBufferBinder binder(decoder_, id_);
2091 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2092}
2093
[email protected]aa7666122011-09-02 19:45:522094GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2095 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322096}
2097
[email protected]aa7666122011-09-02 19:45:522098GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392099 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572100 group_(group),
[email protected]1d82e822013-04-10 21:32:322101 logger_(&debug_marker_manager_),
[email protected]d3eba342013-04-18 21:11:502102 state_(group_->feature_info(), &logger_),
[email protected]43410e92012-04-20 17:06:282103 unpack_flip_y_(false),
2104 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172105 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242106 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492107 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242108 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402109 fixed_attrib_buffer_id_(0),
2110 fixed_attrib_buffer_size_(0),
[email protected]88a61bf2012-10-27 13:00:422111 clear_state_dirty_(true),
[email protected]34ff8b0c2010-10-01 20:06:022112 offscreen_target_color_format_(0),
2113 offscreen_target_depth_format_(0),
2114 offscreen_target_stencil_format_(0),
2115 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562116 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052117 offscreen_saved_color_format_(0),
[email protected]b0af4f52011-09-28 22:04:422118 stream_texture_manager_(NULL),
[email protected]32fe9aa2011-01-21 23:47:132119 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462120 back_buffer_has_depth_(false),
2121 back_buffer_has_stencil_(false),
[email protected]60f22d32012-12-12 00:31:582122 backbuffer_needs_clear_bits_(0),
[email protected]473c01ccb2011-06-07 01:33:302123 teximage2d_faster_than_texsubimage2d_(true),
[email protected]a3a93e7b2010-08-28 00:48:562124 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052125 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112126 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002127 feature_info_(group_->feature_info()),
[email protected]65225772011-05-12 21:10:242128 tex_image_2d_failed_(false),
[email protected]38d139d2011-07-14 00:38:432129 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302130 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512131 reset_status_(GL_NO_ERROR),
[email protected]f0d74742011-10-03 16:31:042132 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102133 derivatives_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282134 compile_shader_always_succeeds_(false),
[email protected]cae20172012-12-07 00:06:192135 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2136 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022137 viewport_max_width_(0),
2138 viewport_max_height_(0),
[email protected]63b465922012-09-06 02:04:522139 texture_upload_count_(0) {
[email protected]3b1ecc262011-08-03 22:49:572140 DCHECK(group);
2141
[email protected]b1122982010-05-17 23:04:242142 attrib_0_value_.v[0] = 0.0f;
2143 attrib_0_value_.v[1] = 0.0f;
2144 attrib_0_value_.v[2] = 0.0f;
2145 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152146
[email protected]c2f8c8402010-12-06 18:07:242147 // The shader translator is used for WebGL even when running on EGL
2148 // because additional restrictions are needed (like only enabling
2149 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562150 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2151 // the empty string to CompileShader and this is not a valid shader.
2152 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002153 CommandLine::ForCurrentProcess()->HasSwitch(
2154 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152155 use_shader_translator_ = false;
2156 }
[email protected]473c01ccb2011-06-07 01:33:302157
[email protected]a39370652012-09-25 21:52:132158 // TODO(gman): Consider setting this based on GPU and/or driver.
[email protected]473c01ccb2011-06-07 01:33:302159 if (IsAngle()) {
2160 teximage2d_faster_than_texsubimage2d_ = false;
[email protected]473c01ccb2011-06-07 01:33:302161 }
[email protected]96449d2c2009-11-25 00:01:322162}
2163
[email protected]80eb6b52012-01-19 00:14:412164GLES2DecoderImpl::~GLES2DecoderImpl() {
2165}
2166
[email protected]c410da802011-03-14 19:17:412167bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382168 const scoped_refptr<gfx::GLSurface>& surface,
2169 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232170 bool offscreen,
[email protected]c410da802011-03-14 19:17:412171 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292172 const DisallowedFeatures& disallowed_features,
[email protected]c410da802011-03-14 19:17:412173 const char* allowed_extensions,
[email protected]3c644d82011-06-20 19:58:242174 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322175 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382176 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302177 DCHECK(!context_.get());
2178
[email protected]55e136f2013-04-03 18:50:062179 set_initialized();
[email protected]fb97b662013-02-20 23:02:142180 gpu_tracer_ = GPUTracer::Create();
2181
[email protected]e844ae22012-01-14 03:36:262182 if (CommandLine::ForCurrentProcess()->HasSwitch(
2183 switches::kEnableGPUDebugging)) {
2184 set_debug(true);
2185 }
2186
[email protected]39ba4f02012-03-26 01:16:002187 if (CommandLine::ForCurrentProcess()->HasSwitch(
2188 switches::kEnableGPUCommandLogging)) {
2189 set_log_commands(true);
2190 }
2191
[email protected]062c38b2012-01-18 03:25:102192 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2193 switches::kCompileShaderAlwaysSucceeds);
2194
[email protected]f62a5ab2011-05-23 20:34:152195
[email protected]63c9b052012-05-17 18:27:382196 // Take ownership of the context and surface. The surface can be replaced with
2197 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382198 context_ = context;
[email protected]63c9b052012-05-17 18:27:382199 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182200
[email protected]c4485aad62012-12-17 10:19:092201 if (!group_->Initialize(this, disallowed_features, allowed_extensions)) {
[email protected]09ddb91f2011-04-14 23:16:222202 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392203 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422204 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382205 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032206 return false;
[email protected]a3ded6d2010-10-19 06:44:392207 }
[email protected]b64c24952012-04-19 03:20:272208 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282209
[email protected]e82fb792011-09-22 00:33:292210 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502211
[email protected]af6380962012-11-29 23:24:132212 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]944b62f32012-09-27 02:20:462213 default_vertex_attrib_manager_ = new VertexAttribManager();
2214 default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs());
2215
[email protected]ab4fd7282012-10-12 16:25:572216 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call
2217 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322218
[email protected]d6ca4792012-05-14 19:24:132219 query_manager_.reset(new QueryManager(this, feature_info_));
[email protected]944b62f32012-09-27 02:20:462220 vertex_array_manager_.reset(new VertexArrayManager());
[email protected]882ba1e22012-03-08 19:02:532221
[email protected]302ce6d2011-07-07 23:28:112222 util_.set_num_compressed_texture_formats(
2223 validators_->compressed_texture_format.GetValues().size());
2224
[email protected]1071e572011-02-09 20:00:122225 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2226 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2227 // OpenGL ES 2.0 does not have this issue.
2228 glEnableVertexAttribArray(0);
2229 }
[email protected]b1122982010-05-17 23:04:242230 glGenBuffersARB(1, &attrib_0_buffer_id_);
2231 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2232 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2233 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402234 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082235
[email protected]1868a342012-11-07 15:56:022236 state_.texture_units.resize(group_->max_texture_units());
2237 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492238 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312239 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492240 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152241 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492242 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072243 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492244 state_.texture_units[tt].bound_texture_external_oes = ref;
2245 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref->service_id());
[email protected]61eeb33f2011-07-26 15:30:312246 }
[email protected]62e155e2012-10-23 22:43:152247 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492248 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072249 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492250 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
2251 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref->service_id());
[email protected]e51bdf32011-11-23 22:21:462252 }
[email protected]370eaf12013-05-18 09:19:492253 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2254 state_.texture_units[tt].bound_texture_cube_map = ref;
2255 glBindTexture(GL_TEXTURE_CUBE_MAP, ref->service_id());
2256 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2257 state_.texture_units[tt].bound_texture_2d = ref;
2258 glBindTexture(GL_TEXTURE_2D, ref->service_id());
[email protected]1958e0e2010-04-22 05:17:152259 }
[email protected]00f893d2010-08-24 18:55:492260 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502261 CHECK_GL_ERROR();
2262
[email protected]297ca1c2011-06-20 23:08:462263 ContextCreationAttribParser attrib_parser;
2264 if (!attrib_parser.Parse(attribs))
2265 return false;
[email protected]41c56362011-06-14 16:47:432266
[email protected]069944672012-04-25 20:52:232267 if (offscreen) {
[email protected]34ff8b0c2010-10-01 20:06:022268 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
[email protected]b0609652012-12-14 07:24:542269 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022270 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432271 // max_sample_count must be initialized to a sane value. If
2272 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2273 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022274 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2275 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2276 max_sample_count);
2277 } else {
2278 offscreen_target_samples_ = 1;
2279 }
[email protected]8a61d872012-01-20 12:43:562280 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
[email protected]34ff8b0c2010-10-01 20:06:022281
2282 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2283 const bool rgb8_supported =
2284 context_->HasExtension("GL_OES_rgb8_rgba8");
2285 // The only available default render buffer formats in GLES2 have very
2286 // little precision. Don't enable multisampling unless 8-bit render
2287 // buffer formats are available--instead fall back to 8-bit textures.
2288 if (rgb8_supported && offscreen_target_samples_ > 1) {
2289 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2290 GL_RGBA8 : GL_RGB8;
2291 } else {
2292 offscreen_target_samples_ = 1;
2293 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2294 GL_RGBA : GL_RGB;
2295 }
2296
2297 // ANGLE only supports packed depth/stencil formats, so use it if it is
2298 // available.
2299 const bool depth24_stencil8_supported =
2300 context_->HasExtension("GL_OES_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272301 VLOG(1) << "GL_OES_packed_depth_stencil "
2302 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]71ee3642010-10-14 18:08:002303 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2304 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022305 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2306 offscreen_target_stencil_format_ = 0;
2307 } else {
2308 // It may be the case that this depth/stencil combination is not
2309 // supported, but this will be checked later by CheckFramebufferStatus.
2310 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2311 GL_DEPTH_COMPONENT16 : 0;
2312 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2313 GL_STENCIL_INDEX8 : 0;
2314 }
2315 } else {
2316 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2317 GL_RGBA : GL_RGB;
2318
2319 // If depth is requested at all, use the packed depth stencil format if
2320 // it's available, as some desktop GL drivers don't support any non-packed
2321 // formats for depth attachments.
2322 const bool depth24_stencil8_supported =
2323 context_->HasExtension("GL_EXT_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272324 VLOG(1) << "GL_EXT_packed_depth_stencil "
2325 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022326
[email protected]71ee3642010-10-14 18:08:002327 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2328 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022329 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2330 offscreen_target_stencil_format_ = 0;
2331 } else {
2332 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2333 GL_DEPTH_COMPONENT : 0;
2334 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2335 GL_STENCIL_INDEX : 0;
2336 }
2337 }
2338
[email protected]97872062010-11-03 19:07:052339 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2340 GL_RGBA : GL_RGB;
2341
[email protected]6217d392010-03-25 22:08:352342 // Create the target frame buffer. This is the one that the client renders
2343 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352344 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352345 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022346 // Due to GLES2 format limitations, either the color texture (for
2347 // non-multisampling) or the color render buffer (for multisampling) will be
2348 // attached to the offscreen frame buffer. The render buffer has more
2349 // limited formats available to it, but the texture can't do multisampling.
2350 if (IsOffscreenBufferMultisampled()) {
[email protected]ed9f9cd2013-02-27 21:12:352351 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022352 offscreen_target_color_render_buffer_->Create();
2353 } else {
[email protected]ed9f9cd2013-02-27 21:12:352354 offscreen_target_color_texture_.reset(new BackTexture(this));
[email protected]34ff8b0c2010-10-01 20:06:022355 offscreen_target_color_texture_->Create();
2356 }
[email protected]ed9f9cd2013-02-27 21:12:352357 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]b9363b22010-06-09 22:06:152358 offscreen_target_depth_render_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:352359 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(this));
[email protected]b9363b22010-06-09 22:06:152360 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352361
2362 // Create the saved offscreen texture. The target frame buffer is copied
2363 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352364 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022365 offscreen_saved_frame_buffer_->Create();
2366 //
[email protected]ed9f9cd2013-02-27 21:12:352367 offscreen_saved_color_texture_.reset(new BackTexture(this));
[email protected]6217d392010-03-25 22:08:352368 offscreen_saved_color_texture_->Create();
2369
[email protected]6217d392010-03-25 22:08:352370 // Allocate the render buffers at their initial size and check the status
2371 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592372 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012373 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382374 Destroy(true);
[email protected]6217d392010-03-25 22:08:352375 return false;
2376 }
2377
[email protected]678a73f2012-12-19 19:22:092378 // Allocate the offscreen saved color texture.
2379 DCHECK(offscreen_saved_color_format_);
2380 offscreen_saved_color_texture_->AllocateStorage(
2381 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2382
2383 offscreen_saved_frame_buffer_->AttachRenderTexture(
2384 offscreen_saved_color_texture_.get());
2385 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2386 GL_FRAMEBUFFER_COMPLETE) {
2387 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2388 Destroy(true);
2389 return false;
2390 }
2391
[email protected]6217d392010-03-25 22:08:352392 // Bind to the new default frame buffer (the offscreen target frame buffer).
2393 // This should now be associated with ID zero.
2394 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102395 } else {
2396 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2397 // These are NOT if the back buffer has these proprorties. They are
2398 // if we want the command buffer to enforce them regardless of what
2399 // the real backbuffer is assuming the real back buffer gives us more than
2400 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2401 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2402 // can't do anything about that.
2403
2404 GLint v = 0;
2405 glGetIntegerv(GL_ALPHA_BITS, &v);
2406 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2407 // user requested RGB then RGB. If the user did not specify a preference
2408 // than use whatever we were given. Same for DEPTH and STENCIL.
2409 back_buffer_color_format_ =
2410 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2411 glGetIntegerv(GL_DEPTH_BITS, &v);
2412 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2413 glGetIntegerv(GL_STENCIL_BITS, &v);
2414 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
[email protected]6217d392010-03-25 22:08:352415 }
2416
[email protected]76a0ee102010-04-07 21:03:042417 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2418 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2419 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372420 // mailing list archives. It also implicitly enables the desktop GL
2421 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2422 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152423 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2424 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372425 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152426 }
[email protected]de17df392010-04-23 21:09:412427
[email protected]706b69f2012-07-27 04:59:302428 has_robustness_extension_ =
2429 context->HasExtension("GL_ARB_robustness") ||
2430 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432431
[email protected]c2f8c8402010-12-06 18:07:242432 if (!InitializeShaderTranslator()) {
2433 return false;
[email protected]de17df392010-04-23 21:09:412434 }
[email protected]76a0ee102010-04-07 21:03:042435
[email protected]e259eb412012-10-13 05:47:242436 state_.viewport_width = size.width();
2437 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282438
[email protected]5904806b2012-05-08 18:10:222439 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282440 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022441 viewport_max_width_ = viewport_params[0];
2442 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282443
[email protected]88a61bf2012-10-27 13:00:422444 state_.scissor_width = state_.viewport_width;
2445 state_.scissor_height = state_.viewport_height;
2446
[email protected]11f3e702012-06-19 19:00:012447 // Set all the default state because some GL drivers get it wrong.
[email protected]f731b9462012-10-30 00:35:222448 state_.InitCapabilities();
2449 state_.InitState();
[email protected]e259eb412012-10-13 05:47:242450 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]88a61bf2012-10-27 13:00:422451 glHint(GL_GENERATE_MIPMAP_HINT, state_.hint_generate_mipmap);
[email protected]e259eb412012-10-13 05:47:242452 glPixelStorei(GL_PACK_ALIGNMENT, state_.pack_alignment);
[email protected]e259eb412012-10-13 05:47:242453 glPixelStorei(GL_UNPACK_ALIGNMENT, state_.unpack_alignment);
[email protected]11f3e702012-06-19 19:00:012454
2455 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2456 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2457 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2458 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2459
[email protected]561cc0a62013-05-07 18:34:452460 // Clear the backbuffer.
2461 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2462
[email protected]62e155e2012-10-23 22:43:152463 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462464 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2465 }
[email protected]dd289a5d62012-06-30 22:05:462466
[email protected]9b753992013-04-27 02:04:412467 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2468 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242469 }
[email protected]85cb4682013-04-20 00:54:242470
[email protected]97419c02013-04-10 02:52:382471 // Only compositor contexts are known to use only the subset of GL
2472 // that can be safely migrated between the iGPU and the dGPU. Mark
2473 // those contexts as safe to forcibly transition between the GPUs.
2474 // http://crbug.com/180876, http://crbug.com/227228
2475 if (!offscreen)
2476 context_->SetSafeToForceGpuSwitch();
2477
[email protected]85a4ac22013-05-31 01:58:472478 async_pixel_transfer_manager_.reset(
2479 new AsyncPixelTransferManager(texture_manager(), context.get()));
[email protected]32145a92012-12-17 09:01:592480
[email protected]246a70452010-03-05 21:53:502481 return true;
[email protected]96449d2c2009-11-25 00:01:322482}
2483
[email protected]302ce6d2011-07-07 23:28:112484void GLES2DecoderImpl::UpdateCapabilities() {
2485 util_.set_num_compressed_texture_formats(
2486 validators_->compressed_texture_format.GetValues().size());
2487 util_.set_num_shader_binary_formats(
2488 validators_->shader_binary_format.GetValues().size());
2489}
2490
[email protected]c2f8c8402010-12-06 18:07:242491bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442492 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2493
[email protected]c2f8c8402010-12-06 18:07:242494 if (!use_shader_translator_) {
2495 return true;
2496 }
2497 ShBuiltInResources resources;
2498 ShInitBuiltInResources(&resources);
2499 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2500 resources.MaxVertexUniformVectors =
2501 group_->max_vertex_uniform_vectors();
2502 resources.MaxVaryingVectors = group_->max_varying_vectors();
2503 resources.MaxVertexTextureImageUnits =
2504 group_->max_vertex_texture_image_units();
2505 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2506 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2507 resources.MaxFragmentUniformVectors =
2508 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492509 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242510 resources.MaxExpressionComplexity = 256;
2511 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042512
[email protected]9e98f61b2013-03-05 02:21:142513#if (ANGLE_SH_VERSION >= 110)
[email protected]46c86752013-05-21 05:08:392514 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212515 GLint precision = 0;
2516 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2517 range, &precision);
2518 resources.FragmentPrecisionHigh = ((range[0] >= 62) &&
2519 (range[1] >= 62) &&
2520 (precision >= 16));
[email protected]9e98f61b2013-03-05 02:21:142521#endif
2522
[email protected]f0d74742011-10-03 16:31:042523 if (force_webgl_glsl_validation_) {
2524 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
2525 } else {
2526 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152527 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462528 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152529 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062530 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152531 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492532 resources.EXT_draw_buffers =
2533 features().ext_draw_buffers ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042534 }
2535
[email protected]26b61442013-03-17 16:12:012536 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2537 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052538 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022539#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]6aedcdc2013-01-24 01:25:052540 resources.HashFunction = &CityHashForAngle;
[email protected]3d944a82013-02-12 19:09:022541#else
2542 resources.HashFunction = &CityHash64;
2543#endif
[email protected]6aedcdc2013-01-24 01:25:052544 else
2545 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122546 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2547 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2548 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
2549 ShaderTranslatorInterface::GlslBuiltInFunctionBehavior function_behavior =
[email protected]62e155e2012-10-23 22:43:152550 workarounds().needs_glsl_built_in_function_emulation ?
[email protected]a2a0fe762011-09-20 00:59:122551 ShaderTranslatorInterface::kGlslBuiltInFunctionEmulated :
2552 ShaderTranslatorInterface::kGlslBuiltInFunctionOriginal;
[email protected]87fb6ab2012-06-13 22:28:042553
2554 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance();
2555 vertex_translator_ = cache->GetTranslator(
2556 SH_VERTEX_SHADER, shader_spec, &resources,
2557 implementation_type, function_behavior);
2558 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242559 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382560 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242561 return false;
2562 }
[email protected]87fb6ab2012-06-13 22:28:042563
2564 fragment_translator_ = cache->GetTranslator(
2565 SH_FRAGMENT_SHADER, shader_spec, &resources,
2566 implementation_type, function_behavior);
2567 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242568 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382569 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242570 return false;
2571 }
2572 return true;
2573}
2574
[email protected]ae51d192010-04-27 00:48:032575bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472576 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352577 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032578 return false;
2579 }
2580 }
[email protected]40d90a22013-04-09 03:39:552581 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032582 glGenBuffersARB(n, service_ids.get());
2583 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352584 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032585 }
2586 return true;
2587}
2588
2589bool GLES2DecoderImpl::GenFramebuffersHelper(
2590 GLsizei n, const GLuint* client_ids) {
2591 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352592 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032593 return false;
2594 }
2595 }
[email protected]40d90a22013-04-09 03:39:552596 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032597 glGenFramebuffersEXT(n, service_ids.get());
2598 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352599 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032600 }
2601 return true;
2602}
2603
2604bool GLES2DecoderImpl::GenRenderbuffersHelper(
2605 GLsizei n, const GLuint* client_ids) {
2606 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352607 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032608 return false;
2609 }
2610 }
[email protected]40d90a22013-04-09 03:39:552611 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032612 glGenRenderbuffersEXT(n, service_ids.get());
2613 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352614 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032615 }
2616 return true;
2617}
2618
2619bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2620 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352621 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032622 return false;
2623 }
2624 }
[email protected]40d90a22013-04-09 03:39:552625 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032626 glGenTextures(n, service_ids.get());
2627 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352628 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032629 }
2630 return true;
2631}
2632
2633void GLES2DecoderImpl::DeleteBuffersHelper(
2634 GLsizei n, const GLuint* client_ids) {
2635 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212636 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102637 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242638 state_.vertex_attrib_manager->Unbind(buffer);
2639 if (state_.bound_array_buffer == buffer) {
2640 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102641 }
[email protected]ed9f9cd2013-02-27 21:12:352642 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032643 }
[email protected]a93bb842010-02-16 23:03:472644 }
[email protected]07f54fcc2009-12-22 02:46:302645}
2646
[email protected]ae51d192010-04-27 00:48:032647void GLES2DecoderImpl::DeleteFramebuffersHelper(
2648 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452649 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152650 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112651
[email protected]a25fa872010-03-25 02:57:582652 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352653 Framebuffer* framebuffer =
2654 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102655 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242656 if (framebuffer == state_.bound_draw_framebuffer) {
2657 state_.bound_draw_framebuffer = NULL;
[email protected]88a61bf2012-10-27 13:00:422658 clear_state_dirty_ = true;
[email protected]ebfb73c2012-08-15 02:37:452659 GLenum target = supports_separate_framebuffer_binds ?
2660 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112661 glBindFramebufferEXT(target, GetBackbufferServiceId());
2662 }
[email protected]e259eb412012-10-13 05:47:242663 if (framebuffer == state_.bound_read_framebuffer) {
2664 state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452665 GLenum target = supports_separate_framebuffer_binds ?
2666 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112667 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462668 }
[email protected]70d34263c2013-01-09 00:27:452669 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352670 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032671 }
[email protected]a25fa872010-03-25 02:57:582672 }
[email protected]07f54fcc2009-12-22 02:46:302673}
2674
[email protected]ae51d192010-04-27 00:48:032675void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2676 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452677 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152678 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582679 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352680 Renderbuffer* renderbuffer =
2681 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102682 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242683 if (state_.bound_renderbuffer == renderbuffer) {
2684 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102685 }
2686 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452687 if (supports_separate_framebuffer_binds) {
[email protected]e259eb412012-10-13 05:47:242688 if (state_.bound_read_framebuffer) {
2689 state_.bound_read_framebuffer->UnbindRenderbuffer(
[email protected]ebfb73c2012-08-15 02:37:452690 GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102691 }
[email protected]e259eb412012-10-13 05:47:242692 if (state_.bound_draw_framebuffer) {
2693 state_.bound_draw_framebuffer->UnbindRenderbuffer(
[email protected]ebfb73c2012-08-15 02:37:452694 GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102695 }
2696 } else {
[email protected]e259eb412012-10-13 05:47:242697 if (state_.bound_draw_framebuffer) {
2698 state_.bound_draw_framebuffer->UnbindRenderbuffer(
[email protected]a0b78dc2011-11-11 10:43:102699 GL_FRAMEBUFFER, renderbuffer);
2700 }
2701 }
[email protected]88a61bf2012-10-27 13:00:422702 clear_state_dirty_ = true;
[email protected]ed9f9cd2013-02-27 21:12:352703 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032704 }
[email protected]a25fa872010-03-25 02:57:582705 }
[email protected]07f54fcc2009-12-22 02:46:302706}
2707
[email protected]ae51d192010-04-27 00:48:032708void GLES2DecoderImpl::DeleteTexturesHelper(
2709 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452710 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152711 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472712 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:492713 TextureRef* texture_ref = GetTexture(client_ids[ii]);
2714 if (texture_ref) {
2715 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:102716 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:422717 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462718 }
[email protected]370eaf12013-05-18 09:19:492719 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:022720 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:492721 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102722 }
2723 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452724 if (supports_separate_framebuffer_binds) {
[email protected]e259eb412012-10-13 05:47:242725 if (state_.bound_read_framebuffer) {
2726 state_.bound_read_framebuffer->UnbindTexture(
[email protected]370eaf12013-05-18 09:19:492727 GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102728 }
[email protected]e259eb412012-10-13 05:47:242729 if (state_.bound_draw_framebuffer) {
2730 state_.bound_draw_framebuffer->UnbindTexture(
[email protected]370eaf12013-05-18 09:19:492731 GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102732 }
2733 } else {
[email protected]e259eb412012-10-13 05:47:242734 if (state_.bound_draw_framebuffer) {
[email protected]370eaf12013-05-18 09:19:492735 state_.bound_draw_framebuffer->UnbindTexture(GL_FRAMEBUFFER,
2736 texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102737 }
2738 }
2739 GLuint service_id = texture->service_id();
2740 if (texture->IsStreamTexture() && stream_texture_manager_) {
[email protected]b0af4f52011-09-28 22:04:422741 stream_texture_manager_->DestroyStreamTexture(service_id);
2742 }
[email protected]e51bdf32011-11-23 22:21:462743#if defined(OS_MACOSX)
2744 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
2745 ReleaseIOSurfaceForTexture(service_id);
2746 }
2747#endif
[email protected]ed9f9cd2013-02-27 21:12:352748 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032749 }
[email protected]a93bb842010-02-16 23:03:472750 }
[email protected]07f54fcc2009-12-22 02:46:302751}
2752
[email protected]43f28f832010-02-03 02:28:482753// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:322754
[email protected]eb54a562010-01-20 21:55:182755bool GLES2DecoderImpl::MakeCurrent() {
[email protected]63c9b052012-05-17 18:27:382756 if (!context_.get() || !context_->MakeCurrent(surface_.get()))
2757 return false;
2758
2759 if (WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:432760 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:292761
2762 // Some D3D drivers cannot recover from device lost in the GPU process
2763 // sandbox. Allow a new GPU process to launch.
2764 if (workarounds().exit_on_context_lost) {
2765 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
2766 << " a D3D device in the Chrome GPU process sandbox.";
2767 exit(0);
2768 }
2769
[email protected]63c9b052012-05-17 18:27:382770 return false;
[email protected]38d139d2011-07-14 00:38:432771 }
2772
[email protected]69a8701e2013-03-07 21:31:092773 ProcessFinishedAsyncTransfers();
2774 if (workarounds().flush_on_context_switch)
2775 glFlush();
2776
[email protected]9b753992013-04-27 02:04:412777 // Rebind the FBO if it was unbound by the context.
2778 if (workarounds().unbind_fbo_on_context_switch)
2779 RestoreFramebufferBindings();
2780
[email protected]370eaf12013-05-18 09:19:492781 clear_state_dirty_ = true;
2782
[email protected]69a8701e2013-03-07 21:31:092783 return true;
2784}
2785
2786void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]fe8d73c2013-02-16 22:37:322787 if (engine() && query_manager_.get())
2788 query_manager_->ProcessPendingTransferQueries();
2789
[email protected]5b3a8e02013-03-13 05:36:442790 // TODO(epenner): Is there a better place to do this?
2791 // This needs to occur before we execute any batch of commands
2792 // from the client, as the client may have recieved an async
2793 // completion while issuing those commands.
2794 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]85a4ac22013-05-31 01:58:472795 GetAsyncPixelTransferDelegate()->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:182796}
2797
[email protected]a96a6022011-11-04 00:58:122798void GLES2DecoderImpl::ReleaseCurrent() {
2799 if (context_.get())
2800 context_->ReleaseCurrent(surface_.get());
2801}
2802
[email protected]8e3e0662010-08-23 18:46:302803void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() {
[email protected]ed9f9cd2013-02-27 21:12:352804 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:202805 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
[email protected]8e3e0662010-08-23 18:46:302806 glBindRenderbufferEXT(
[email protected]0d6bfdc2011-11-02 01:32:202807 GL_RENDERBUFFER, renderbuffer ? renderbuffer->service_id() : 0);
[email protected]8e3e0662010-08-23 18:46:302808}
2809
2810static void RebindCurrentFramebuffer(
2811 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:062812 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:242813 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:062814 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:462815
[email protected]a3783712012-01-20 22:18:242816 if (framebuffer_id == 0) {
2817 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:302818 }
[email protected]297ca1c2011-06-20 23:08:462819
[email protected]8e3e0662010-08-23 18:46:302820 glBindFramebufferEXT(target, framebuffer_id);
2821}
2822
2823void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]88a61bf2012-10-27 13:00:422824 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:462825
[email protected]62e155e2012-10-23 22:43:152826 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:302827 RebindCurrentFramebuffer(
2828 GL_FRAMEBUFFER,
[email protected]e259eb412012-10-13 05:47:242829 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242830 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302831 } else {
2832 RebindCurrentFramebuffer(
2833 GL_READ_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242834 state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242835 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302836 RebindCurrentFramebuffer(
2837 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]e259eb412012-10-13 05:47:242838 state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242839 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302840 }
[email protected]70d34263c2013-01-09 00:27:452841 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:302842}
2843
2844void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() {
[email protected]e259eb412012-10-13 05:47:242845 TextureUnit& info = state_.texture_units[0];
[email protected]8e3e0662010-08-23 18:46:302846 GLuint last_id;
2847 if (info.bound_texture_2d) {
2848 last_id = info.bound_texture_2d->service_id();
2849 } else {
2850 last_id = 0;
2851 }
2852
2853 glBindTexture(GL_TEXTURE_2D, last_id);
[email protected]e259eb412012-10-13 05:47:242854 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]8e3e0662010-08-23 18:46:302855}
2856
[email protected]0d6bfdc2011-11-02 01:32:202857bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:352858 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:202859 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:102860 if (!framebuffer) {
[email protected]60f22d32012-12-12 00:31:582861 if (backbuffer_needs_clear_bits_) {
2862 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
2863 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
2864 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2865 glClearStencil(0);
2866 glStencilMask(-1);
2867 glClearDepth(1.0f);
2868 glDepthMask(true);
2869 glDisable(GL_SCISSOR_TEST);
2870 glClear(backbuffer_needs_clear_bits_);
2871 backbuffer_needs_clear_bits_ = 0;
2872 RestoreClearState();
2873 }
[email protected]0d6bfdc2011-11-02 01:32:202874 return true;
2875 }
2876
[email protected]968351b2011-12-20 08:26:512877 if (framebuffer_manager()->IsComplete(framebuffer)) {
2878 return true;
2879 }
2880
[email protected]0d6bfdc2011-11-02 01:32:202881 GLenum completeness = framebuffer->IsPossiblyComplete();
2882 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512883 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432884 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:272885 return false;
2886 }
[email protected]0d6bfdc2011-11-02 01:32:202887
2888 // Are all the attachments cleared?
2889 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
2890 texture_manager()->HaveUnclearedMips()) {
2891 if (!framebuffer->IsCleared()) {
2892 // Can we clear them?
[email protected]73276522012-11-09 05:50:202893 if (framebuffer->GetStatus(texture_manager(), target) !=
2894 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512895 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432896 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2897 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:202898 return false;
2899 }
2900 ClearUnclearedAttachments(target, framebuffer);
2901 }
2902 }
2903
[email protected]968351b2011-12-20 08:26:512904 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:202905 if (framebuffer->GetStatus(texture_manager(), target) !=
2906 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512907 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432908 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2909 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:512910 return false;
2911 }
2912 framebuffer_manager()->MarkAsComplete(framebuffer);
2913 }
2914
[email protected]0d6bfdc2011-11-02 01:32:202915 // NOTE: At this point we don't know if the framebuffer is complete but
2916 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:272917 return true;
2918}
2919
[email protected]0d6bfdc2011-11-02 01:32:202920bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:152921 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:512922 bool valid = CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242923 state_.bound_draw_framebuffer, GL_FRAMEBUFFER_EXT, func_name);
[email protected]28718a92013-04-04 12:12:512924
2925 if (valid)
2926 OnUseFramebuffer();
2927
2928 return valid;
[email protected]0d6bfdc2011-11-02 01:32:202929 }
2930 return CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242931 state_.bound_draw_framebuffer,
2932 GL_DRAW_FRAMEBUFFER_EXT, func_name) &&
[email protected]0d6bfdc2011-11-02 01:32:202933 CheckFramebufferValid(
[email protected]e259eb412012-10-13 05:47:242934 state_.bound_read_framebuffer,
2935 GL_READ_FRAMEBUFFER_EXT, func_name);
[email protected]0d6bfdc2011-11-02 01:32:202936}
2937
[email protected]8e3e0662010-08-23 18:46:302938gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:352939 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452940 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202941 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:352942 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:202943 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:262944 if (attachment) {
2945 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:502946 }
[email protected]9edc6b22010-12-23 02:00:262947 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:022948 } else if (offscreen_target_frame_buffer_.get()) {
2949 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:352950 } else {
[email protected]f62a5ab2011-05-23 20:34:152951 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:022952 }
[email protected]246a70452010-03-05 21:53:502953}
2954
[email protected]9edc6b22010-12-23 02:00:262955GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:352956 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452957 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202958 if (framebuffer != NULL) {
2959 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:462960 } else if (offscreen_target_frame_buffer_.get()) {
2961 return offscreen_target_color_format_;
2962 } else {
2963 return back_buffer_color_format_;
2964 }
2965}
2966
2967GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:352968 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452969 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202970 if (framebuffer != NULL) {
2971 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:262972 } else if (offscreen_target_frame_buffer_.get()) {
2973 return offscreen_target_color_format_;
2974 } else {
[email protected]32fe9aa2011-01-21 23:47:132975 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:262976 }
2977}
2978
[email protected]9a5afa432011-07-22 18:16:392979void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]34ff8b0c2010-10-01 20:06:022980 if (parent_) {
[email protected]2f2d7042010-04-14 21:45:582981 // Update the info about the offscreen saved color texture in the parent.
2982 // The reference to the parent is a weak pointer and will become null if the
2983 // parent is later destroyed.
[email protected]370eaf12013-05-18 09:19:492984 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
[email protected]262d7aa2010-12-03 22:07:292985 TextureManager* parent_texture_manager = parent_->texture_manager();
[email protected]370eaf12013-05-18 09:19:492986 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
[email protected]262d7aa2010-12-03 22:07:292987 parent_texture_manager->SetLevelInfo(
[email protected]8a61d872012-01-20 12:43:562988 offscreen_saved_color_texture_info_,
[email protected]ef526492010-06-02 23:12:252989 GL_TEXTURE_2D,
2990 0, // level
2991 GL_RGBA,
[email protected]799b4b22011-08-22 17:09:592992 offscreen_size_.width(),
2993 offscreen_size_.height(),
[email protected]ef526492010-06-02 23:12:252994 1, // depth
2995 0, // border
2996 GL_RGBA,
[email protected]0d6bfdc2011-11-02 01:32:202997 GL_UNSIGNED_BYTE,
2998 true);
[email protected]262d7aa2010-12-03 22:07:292999 parent_texture_manager->SetParameter(
[email protected]02965c22013-03-09 02:40:073000 "UpdateParentTextureInfo",
[email protected]d3eba342013-04-18 21:11:503001 GetErrorState(),
[email protected]8a61d872012-01-20 12:43:563002 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:043003 GL_TEXTURE_MAG_FILTER,
3004 GL_NEAREST);
[email protected]262d7aa2010-12-03 22:07:293005 parent_texture_manager->SetParameter(
[email protected]02965c22013-03-09 02:40:073006 "UpdateParentTextureInfo",
[email protected]d3eba342013-04-18 21:11:503007 GetErrorState(),
[email protected]8a61d872012-01-20 12:43:563008 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:043009 GL_TEXTURE_MIN_FILTER,
3010 GL_NEAREST);
[email protected]262d7aa2010-12-03 22:07:293011 parent_texture_manager->SetParameter(
[email protected]02965c22013-03-09 02:40:073012 "UpdateParentTextureInfo",
[email protected]d3eba342013-04-18 21:11:503013 GetErrorState(),
[email protected]8a61d872012-01-20 12:43:563014 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:043015 GL_TEXTURE_WRAP_S,
3016 GL_CLAMP_TO_EDGE);
[email protected]262d7aa2010-12-03 22:07:293017 parent_texture_manager->SetParameter(
[email protected]02965c22013-03-09 02:40:073018 "UpdateParentTextureInfo",
[email protected]d3eba342013-04-18 21:11:503019 GetErrorState(),
[email protected]8a61d872012-01-20 12:43:563020 offscreen_saved_color_texture_info_,
[email protected]8c515f82010-11-09 03:40:043021 GL_TEXTURE_WRAP_T,
3022 GL_CLAMP_TO_EDGE);
[email protected]370eaf12013-05-18 09:19:493023 TextureRef* texture_ref = GetTextureInfoForTarget(target);
3024 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]8a61d872012-01-20 12:43:563025 } else {
3026 offscreen_saved_color_texture_info_ = NULL;
[email protected]0c8c9d22010-06-25 17:36:393027 }
[email protected]6217d392010-03-25 22:08:353028}
3029
[email protected]799b4b22011-08-22 17:09:593030void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073031 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523032 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003033}
3034
[email protected]1d82e822013-04-10 21:32:323035Logger* GLES2DecoderImpl::GetLogger() {
3036 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523037}
3038
[email protected]d3eba342013-04-18 21:11:503039ErrorState* GLES2DecoderImpl::GetErrorState() {
3040 return state_.GetErrorState();
3041}
3042
[email protected]e3932abb2013-03-13 00:01:373043void GLES2DecoderImpl::SetShaderCacheCallback(
3044 const ShaderCacheCallback& callback) {
3045 shader_cache_callback_ = callback;
3046}
3047
[email protected]840a7e462013-02-27 01:29:513048void GLES2DecoderImpl::SetWaitSyncPointCallback(
3049 const WaitSyncPointCallback& callback) {
3050 wait_sync_point_callback_ = callback;
3051}
3052
[email protected]b0af4f52011-09-28 22:04:423053void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) {
3054 stream_texture_manager_ = manager;
3055}
3056
[email protected]2a7568a2013-05-09 23:12:033057AsyncPixelTransferDelegate*
[email protected]32145a92012-12-17 09:01:593058 GLES2DecoderImpl::GetAsyncPixelTransferDelegate() {
[email protected]85a4ac22013-05-31 01:58:473059 return async_pixel_transfer_manager_->GetAsyncPixelTransferDelegate();
[email protected]32145a92012-12-17 09:01:593060}
3061
[email protected]85a4ac22013-05-31 01:58:473062void GLES2DecoderImpl::SetAsyncPixelTransferDelegateForTest(
[email protected]2a7568a2013-05-09 23:12:033063 AsyncPixelTransferDelegate* delegate) {
[email protected]85a4ac22013-05-31 01:58:473064 async_pixel_transfer_manager_->SetAsyncPixelTransferDelegateForTest(delegate);
3065}
3066
3067AsyncPixelTransferManager*
3068 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3069 return async_pixel_transfer_manager_.get();
3070}
3071
3072void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3073 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593074}
3075
[email protected]1318e922010-09-17 22:03:163076bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3077 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493078 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3079 if (texture_ref) {
3080 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163081 return true;
3082 }
3083 return false;
3084}
3085
[email protected]63b465922012-09-06 02:04:523086uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]b9804322013-01-08 17:54:123087 return texture_upload_count_ +
[email protected]85a4ac22013-05-31 01:58:473088 GetAsyncPixelTransferDelegate()->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523089}
3090
3091base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]b9804322013-01-08 17:54:123092 return total_texture_upload_time_ +
[email protected]85a4ac22013-05-31 01:58:473093 GetAsyncPixelTransferDelegate()->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523094}
3095
3096base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3097 return total_processing_commands_time_;
3098}
3099
[email protected]dc25dda2012-09-27 21:36:303100void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3101 total_processing_commands_time_ += time;
3102}
3103
[email protected]63c9b052012-05-17 18:27:383104void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063105 if (!initialized())
3106 return;
3107
[email protected]63c9b052012-05-17 18:27:383108 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053109
[email protected]c826d732012-02-09 04:40:263110 ChildList children = children_;
3111 for (ChildList::iterator it = children.begin(); it != children.end(); ++it)
3112 (*it)->SetParent(NULL, 0);
3113 DCHECK(children_.empty());
[email protected]3c644d82011-06-20 19:58:243114 SetParent(NULL, 0);
3115
[email protected]80eb6b52012-01-19 00:14:413116 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243117 state_.vertex_attrib_manager = NULL;
[email protected]944b62f32012-09-27 02:20:463118 default_vertex_attrib_manager_ = NULL;
[email protected]1868a342012-11-07 15:56:023119 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243120 state_.bound_array_buffer = NULL;
3121 state_.current_query = NULL;
3122 state_.current_program = NULL;
3123 state_.bound_read_framebuffer = NULL;
3124 state_.bound_draw_framebuffer = NULL;
3125 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413126
[email protected]eadc96792010-10-27 19:39:393127 if (have_context) {
[email protected]c322e882012-05-23 18:06:183128 if (copy_texture_CHROMIUM_.get()) {
3129 copy_texture_CHROMIUM_->Destroy();
3130 copy_texture_CHROMIUM_.reset();
3131 }
[email protected]43410e92012-04-20 17:06:283132
[email protected]e259eb412012-10-13 05:47:243133 if (state_.current_program) {
3134 program_manager()->UnuseProgram(shader_manager(), state_.current_program);
3135 state_.current_program = NULL;
[email protected]ca488e12010-12-13 20:06:143136 }
3137
[email protected]b1122982010-05-17 23:04:243138 if (attrib_0_buffer_id_) {
3139 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3140 }
[email protected]8fbedc02010-11-18 18:43:403141 if (fixed_attrib_buffer_id_) {
3142 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3143 }
[email protected]b1122982010-05-17 23:04:243144
[email protected]97872062010-11-03 19:07:053145 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543146 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053147 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543148 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053149 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023150 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053151 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153152 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053153 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153154 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053155 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023156 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053157 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543158 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273159 if (offscreen_resolved_frame_buffer_.get())
3160 offscreen_resolved_frame_buffer_->Destroy();
3161 if (offscreen_resolved_color_texture_.get())
3162 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053163 } else {
3164 if (offscreen_target_frame_buffer_.get())
3165 offscreen_target_frame_buffer_->Invalidate();
3166 if (offscreen_target_color_texture_.get())
3167 offscreen_target_color_texture_->Invalidate();
3168 if (offscreen_target_color_render_buffer_.get())
3169 offscreen_target_color_render_buffer_->Invalidate();
3170 if (offscreen_target_depth_render_buffer_.get())
3171 offscreen_target_depth_render_buffer_->Invalidate();
3172 if (offscreen_target_stencil_render_buffer_.get())
3173 offscreen_target_stencil_render_buffer_->Invalidate();
3174 if (offscreen_saved_frame_buffer_.get())
3175 offscreen_saved_frame_buffer_->Invalidate();
3176 if (offscreen_saved_color_texture_.get())
3177 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273178 if (offscreen_resolved_frame_buffer_.get())
3179 offscreen_resolved_frame_buffer_->Invalidate();
3180 if (offscreen_resolved_color_texture_.get())
3181 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023182 }
[email protected]43410e92012-04-20 17:06:283183 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053184
[email protected]882ba1e22012-03-08 19:02:533185 if (query_manager_.get()) {
3186 query_manager_->Destroy(have_context);
3187 query_manager_.reset();
3188 }
3189
[email protected]944b62f32012-09-27 02:20:463190 if (vertex_array_manager_ .get()) {
3191 vertex_array_manager_->Destroy(have_context);
3192 vertex_array_manager_.reset();
3193 }
3194
[email protected]97872062010-11-03 19:07:053195 offscreen_target_frame_buffer_.reset();
3196 offscreen_target_color_texture_.reset();
3197 offscreen_target_color_render_buffer_.reset();
3198 offscreen_target_depth_render_buffer_.reset();
3199 offscreen_target_stencil_render_buffer_.reset();
3200 offscreen_saved_frame_buffer_.reset();
3201 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273202 offscreen_resolved_frame_buffer_.reset();
3203 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463204
[email protected]85a4ac22013-05-31 01:58:473205 // Should destroy the transfer manager before the texture manager held
3206 // by the context group.
3207 async_pixel_transfer_manager_.reset();
3208
[email protected]2d9d3b92013-01-18 01:07:233209 if (group_) {
3210 group_->Destroy(this, have_context);
3211 group_ = NULL;
3212 }
3213
3214 if (context_.get()) {
3215 context_->ReleaseCurrent(NULL);
3216 context_ = NULL;
3217 }
3218
[email protected]e51bdf32011-11-23 22:21:463219#if defined(OS_MACOSX)
3220 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3221 it != texture_to_io_surface_map_.end(); ++it) {
3222 CFRelease(it->second);
3223 }
3224 texture_to_io_surface_map_.clear();
3225#endif
[email protected]96449d2c2009-11-25 00:01:323226}
3227
[email protected]63c9b052012-05-17 18:27:383228void GLES2DecoderImpl::SetSurface(
3229 const scoped_refptr<gfx::GLSurface>& surface) {
3230 DCHECK(context_->IsCurrent(NULL));
3231 DCHECK(surface_.get());
3232 surface_ = surface;
3233 RestoreCurrentFramebufferBindings();
3234}
3235
[email protected]3c644d82011-06-20 19:58:243236bool GLES2DecoderImpl::SetParent(GLES2Decoder* new_parent,
3237 uint32 new_parent_texture_id) {
[email protected]9a5afa432011-07-22 18:16:393238 if (!offscreen_saved_color_texture_.get())
3239 return false;
3240
[email protected]3c644d82011-06-20 19:58:243241 // Remove the saved frame buffer mapping from the parent decoder. The
3242 // parent pointer is a weak pointer so it will be null if the parent has
3243 // already been destroyed.
3244 if (parent_) {
[email protected]c826d732012-02-09 04:40:263245 ChildList::iterator it = std::find(
3246 parent_->children_.begin(),
3247 parent_->children_.end(),
3248 this);
3249 DCHECK(it != parent_->children_.end());
3250 parent_->children_.erase(it);
[email protected]3c644d82011-06-20 19:58:243251 // First check the texture has been mapped into the parent. This might not
3252 // be the case if initialization failed midway through.
[email protected]62e65f02013-05-29 22:28:103253 if (offscreen_saved_color_texture_info_ &&
3254 offscreen_saved_color_texture_info_->client_id()) {
3255 parent_->texture_manager()->RemoveTexture(
3256 offscreen_saved_color_texture_info_->client_id());
[email protected]3c644d82011-06-20 19:58:243257 }
3258 }
3259
3260 GLES2DecoderImpl* new_parent_impl = static_cast<GLES2DecoderImpl*>(
3261 new_parent);
3262 if (new_parent_impl) {
[email protected]c826d732012-02-09 04:40:263263#ifndef NDEBUG
3264 ChildList::iterator it = std::find(
3265 new_parent_impl->children_.begin(),
3266 new_parent_impl->children_.end(),
3267 this);
3268 DCHECK(it == new_parent_impl->children_.end());
3269#endif
3270 new_parent_impl->children_.push_back(this);
[email protected]3c644d82011-06-20 19:58:243271 // Map the ID of the saved offscreen texture into the parent so that
3272 // it can reference it.
3273 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]98687862011-07-11 23:31:303274
3275 // Replace texture info when ID is already in use by parent.
[email protected]ed9f9cd2013-02-27 21:12:353276 if (new_parent_impl->texture_manager()->GetTexture(
[email protected]80eb6b52012-01-19 00:14:413277 new_parent_texture_id))
[email protected]ed9f9cd2013-02-27 21:12:353278 new_parent_impl->texture_manager()->RemoveTexture(
[email protected]80eb6b52012-01-19 00:14:413279 new_parent_texture_id);
[email protected]98687862011-07-11 23:31:303280
[email protected]8a61d872012-01-20 12:43:563281 offscreen_saved_color_texture_info_ =
[email protected]ed9f9cd2013-02-27 21:12:353282 new_parent_impl->CreateTexture(new_parent_texture_id, service_id);
[email protected]370eaf12013-05-18 09:19:493283 offscreen_saved_color_texture_info_->texture()->SetNotOwned();
[email protected]8a61d872012-01-20 12:43:563284 new_parent_impl->texture_manager()->
[email protected]02965c22013-03-09 02:40:073285 SetTarget(offscreen_saved_color_texture_info_, GL_TEXTURE_2D);
[email protected]3c644d82011-06-20 19:58:243286
[email protected]ee1e6aa2012-11-29 09:24:103287 parent_ = base::AsWeakPtr<GLES2DecoderImpl>(new_parent_impl);
[email protected]9a5afa432011-07-22 18:16:393288
3289 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243290 } else {
3291 parent_.reset();
[email protected]8a61d872012-01-20 12:43:563292 offscreen_saved_color_texture_info_ = NULL;
[email protected]3c644d82011-06-20 19:58:243293 }
3294
3295 return true;
3296}
3297
[email protected]260ddc4e2012-06-28 00:01:533298size_t GLES2DecoderImpl::GetBackbufferMemoryTotal() {
[email protected]1078f912011-12-23 13:12:143299 size_t total = 0;
3300 if (offscreen_target_frame_buffer_.get()) {
3301 if (offscreen_target_color_texture_.get()) {
3302 total += offscreen_target_color_texture_->estimated_size();
3303 }
3304 if (offscreen_target_color_render_buffer_.get()) {
3305 total += offscreen_target_color_render_buffer_->estimated_size();
3306 }
3307 if (offscreen_target_depth_render_buffer_.get()) {
3308 total += offscreen_target_depth_render_buffer_->estimated_size();
3309 }
3310 if (offscreen_target_stencil_render_buffer_.get()) {
3311 total += offscreen_target_stencil_render_buffer_->estimated_size();
3312 }
3313 if (offscreen_saved_color_texture_.get()) {
3314 total += offscreen_saved_color_texture_->estimated_size();
3315 }
3316 if (offscreen_resolved_color_texture_.get()) {
3317 total += offscreen_resolved_color_texture_->estimated_size();
3318 }
3319 } else {
3320 gfx::Size size = surface_->GetSize();
3321 total += size.width() * size.height() *
3322 GLES2Util::RenderbufferBytesPerPixel(back_buffer_color_format_);
3323 }
[email protected]260ddc4e2012-06-28 00:01:533324 return total;
[email protected]1078f912011-12-23 13:12:143325}
3326
[email protected]799b4b22011-08-22 17:09:593327bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3328 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3329 if (!is_offscreen) {
3330 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3331 << " with an onscreen framebuffer.";
3332 return false;
3333 }
3334
3335 if (offscreen_size_ == size)
3336 return true;
3337
3338 offscreen_size_ = size;
3339 int w = offscreen_size_.width();
3340 int h = offscreen_size_.height();
3341 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3342 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3343 << "to allocate storage due to excessive dimensions.";
3344 return false;
3345 }
3346
3347 // Reallocate the offscreen target buffers.
3348 DCHECK(offscreen_target_color_format_);
3349 if (IsOffscreenBufferMultisampled()) {
3350 if (!offscreen_target_color_render_buffer_->AllocateStorage(
3351 offscreen_size_, offscreen_target_color_format_,
3352 offscreen_target_samples_)) {
3353 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3354 << "to allocate storage for offscreen target color buffer.";
3355 return false;
3356 }
3357 } else {
3358 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093359 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593360 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3361 << "to allocate storage for offscreen target color texture.";
3362 return false;
3363 }
3364 }
3365 if (offscreen_target_depth_format_ &&
3366 !offscreen_target_depth_render_buffer_->AllocateStorage(
3367 offscreen_size_, offscreen_target_depth_format_,
3368 offscreen_target_samples_)) {
3369 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3370 << "to allocate storage for offscreen target depth buffer.";
3371 return false;
3372 }
3373 if (offscreen_target_stencil_format_ &&
3374 !offscreen_target_stencil_render_buffer_->AllocateStorage(
3375 offscreen_size_, offscreen_target_stencil_format_,
3376 offscreen_target_samples_)) {
3377 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3378 << "to allocate storage for offscreen target stencil buffer.";
3379 return false;
3380 }
3381
3382 // Attach the offscreen target buffers to the target frame buffer.
3383 if (IsOffscreenBufferMultisampled()) {
3384 offscreen_target_frame_buffer_->AttachRenderBuffer(
3385 GL_COLOR_ATTACHMENT0,
3386 offscreen_target_color_render_buffer_.get());
3387 } else {
3388 offscreen_target_frame_buffer_->AttachRenderTexture(
3389 offscreen_target_color_texture_.get());
3390 }
3391 if (offscreen_target_depth_format_) {
3392 offscreen_target_frame_buffer_->AttachRenderBuffer(
3393 GL_DEPTH_ATTACHMENT,
3394 offscreen_target_depth_render_buffer_.get());
3395 }
3396 const bool packed_depth_stencil =
3397 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3398 if (packed_depth_stencil) {
3399 offscreen_target_frame_buffer_->AttachRenderBuffer(
3400 GL_STENCIL_ATTACHMENT,
3401 offscreen_target_depth_render_buffer_.get());
3402 } else if (offscreen_target_stencil_format_) {
3403 offscreen_target_frame_buffer_->AttachRenderBuffer(
3404 GL_STENCIL_ATTACHMENT,
3405 offscreen_target_stencil_render_buffer_.get());
3406 }
3407
3408 if (offscreen_target_frame_buffer_->CheckStatus() !=
3409 GL_FRAMEBUFFER_COMPLETE) {
3410 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3411 << "because offscreen FBO was incomplete.";
3412 return false;
3413 }
3414
3415 // Clear the target frame buffer.
3416 {
3417 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3418 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3419 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3420 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3421 glClearStencil(0);
3422 glStencilMaskSeparate(GL_FRONT, -1);
3423 glStencilMaskSeparate(GL_BACK, -1);
3424 glClearDepth(0);
3425 glDepthMask(GL_TRUE);
3426 glDisable(GL_SCISSOR_TEST);
3427 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3428 RestoreClearState();
3429 }
[email protected]d85ef76d2011-09-08 22:21:433430
3431 // Destroy the offscreen resolved framebuffers.
3432 if (offscreen_resolved_frame_buffer_.get())
3433 offscreen_resolved_frame_buffer_->Destroy();
3434 if (offscreen_resolved_color_texture_.get())
3435 offscreen_resolved_color_texture_->Destroy();
3436 offscreen_resolved_color_texture_.reset();
3437 offscreen_resolved_frame_buffer_.reset();
3438
[email protected]799b4b22011-08-22 17:09:593439 return true;
[email protected]6217d392010-03-25 22:08:353440}
3441
[email protected]799b4b22011-08-22 17:09:593442error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:353443 uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) {
[email protected]09e17272012-11-30 10:30:443444 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023445 return error::kDeferCommandUntilLater;
3446
[email protected]799b4b22011-08-22 17:09:593447 GLuint width = static_cast<GLuint>(c.width);
3448 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073449 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593450 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413451
3452 width = std::max(1U, width);
3453 height = std::max(1U, height);
3454
[email protected]a0d989162011-11-22 13:15:073455#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3456 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003457 // Make sure that we are done drawing to the back buffer before resizing.
3458 glFinish();
3459#endif
[email protected]799b4b22011-08-22 17:09:593460 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3461 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493462 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3463 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3464 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593465 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493466 }
[email protected]7ff86b92010-11-25 17:50:003467 }
[email protected]799b4b22011-08-22 17:09:593468
[email protected]9d37f062011-11-22 01:24:523469 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073470 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443471 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493472 if (!context_->IsCurrent(surface_.get())) {
3473 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3474 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053475 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493476 }
[email protected]658f7562011-09-09 05:24:053477 }
[email protected]799b4b22011-08-22 17:09:593478
3479 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393480}
3481
[email protected]96449d2c2009-11-25 00:01:323482const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3483 if (command_id > kStartPoint && command_id < kNumCommands) {
3484 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3485 }
3486 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3487}
3488
3489// Decode command with its arguments, and call the corresponding GL function.
3490// Note: args is a pointer to the command buffer. As such, it could be changed
3491// by a (malicious) client at any time, so if validation has to happen, it
3492// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143493error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323494 unsigned int command,
3495 unsigned int arg_count,
3496 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143497 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263498 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003499 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
3500 // LOG(INFO), tried VLOG(1), no luck.
[email protected]1d82e822013-04-10 21:32:323501 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" << "cmd: "
[email protected]d2a0e1a2012-08-12 02:25:013502 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193503 }
[email protected]96449d2c2009-11-25 00:01:323504 unsigned int command_index = command - kStartPoint - 1;
3505 if (command_index < arraysize(g_command_info)) {
3506 const CommandInfo& info = g_command_info[command_index];
3507 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3508 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3509 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]b9849abf2009-11-25 19:13:193510 uint32 immediate_data_size =
3511 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323512 switch (command) {
3513 #define GLES2_CMD_OP(name) \
[email protected]ed9f9cd2013-02-27 21:12:353514 case cmds::name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193515 result = Handle ## name( \
3516 immediate_data_size, \
[email protected]ed9f9cd2013-02-27 21:12:353517 *static_cast<const gles2::cmds::name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193518 break; \
[email protected]96449d2c2009-11-25 00:01:323519
3520 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323521 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383522 }
3523 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303524 GLenum error;
3525 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]1d82e822013-04-10 21:32:323526 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003527 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3528 << GetCommandName(command);
[email protected]ab09b612013-03-11 22:11:513529 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193530 }
[email protected]96449d2c2009-11-25 00:01:323531 }
3532 } else {
[email protected]f7a64ee2010-02-01 22:24:143533 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323534 }
[email protected]b9849abf2009-11-25 19:13:193535 } else {
3536 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323537 }
[email protected]a3a93e7b2010-08-28 00:48:563538 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3539 result = current_decoder_error_;
3540 current_decoder_error_ = error::kNoError;
3541 }
[email protected]b9849abf2009-11-25 19:13:193542 return result;
[email protected]96449d2c2009-11-25 00:01:323543}
3544
[email protected]ed9f9cd2013-02-27 21:12:353545void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3546 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503547}
3548
[email protected]ae51d192010-04-27 00:48:033549bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353550 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033551 return false;
3552 }
[email protected]96449d2c2009-11-25 00:01:323553 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033554 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353555 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323556 }
[email protected]ae51d192010-04-27 00:48:033557 return true;
[email protected]96449d2c2009-11-25 00:01:323558}
3559
[email protected]ae51d192010-04-27 00:48:033560bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353561 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033562 return false;
[email protected]96449d2c2009-11-25 00:01:323563 }
[email protected]ae51d192010-04-27 00:48:033564 GLuint service_id = glCreateShader(type);
3565 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353566 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033567 }
3568 return true;
[email protected]96449d2c2009-11-25 00:01:323569}
3570
[email protected]882ba1e22012-03-08 19:02:533571void GLES2DecoderImpl::DoFinish() {
3572 glFinish();
[email protected]22e3f552012-03-13 01:54:193573 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533574}
3575
3576void GLES2DecoderImpl::DoFlush() {
3577 glFlush();
[email protected]22e3f552012-03-13 01:54:193578 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533579}
3580
[email protected]3916c97e2010-02-25 03:20:503581void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453582 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023583 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513584 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533585 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503586 return;
3587 }
[email protected]e259eb412012-10-13 05:47:243588 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453589 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503590}
3591
[email protected]051b1372010-04-12 02:42:083592void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073593 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083594 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033595 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073596 buffer = GetBuffer(client_id);
3597 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353598 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153599 LOG(ERROR) << "glBindBuffer: id not generated by glGenBuffers";
3600 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353601 return;
3602 }
3603
[email protected]b10492f2013-03-08 05:24:073604 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033605 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353606 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073607 buffer = GetBuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573608 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103609 group_->GetIdAllocator(id_namespaces::kBuffers);
3610 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033611 }
[email protected]051b1372010-04-12 02:42:083612 }
[email protected]b10492f2013-03-08 05:24:073613 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3614 if (buffer) {
3615 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513616 LOCAL_SET_GL_ERROR(
3617 GL_INVALID_OPERATION,
3618 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473619 return;
3620 }
[email protected]b10492f2013-03-08 05:24:073621 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473622 }
[email protected]96449d2c2009-11-25 00:01:323623 switch (target) {
3624 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073625 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323626 break;
3627 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073628 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323629 break;
3630 default:
[email protected]a93bb842010-02-16 23:03:473631 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323632 break;
3633 }
[email protected]051b1372010-04-12 02:42:083634 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323635}
3636
[email protected]297ca1c2011-06-20 23:08:463637bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha() {
3638 return (GLES2Util::GetChannelsForFormat(
3639 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3640}
3641
3642bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353643 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453644 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203645 if (framebuffer) {
3646 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463647 }
3648 if (offscreen_target_frame_buffer_.get()) {
3649 return offscreen_target_depth_format_ != 0;
3650 }
3651 return back_buffer_has_depth_;
3652}
3653
3654bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353655 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453656 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203657 if (framebuffer) {
3658 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463659 }
3660 if (offscreen_target_frame_buffer_.get()) {
3661 return offscreen_target_stencil_format_ != 0 ||
3662 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3663 }
3664 return back_buffer_has_stencil_;
3665}
3666
3667void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]88a61bf2012-10-27 13:00:423668 if (clear_state_dirty_) {
[email protected]297ca1c2011-06-20 23:08:463669 glColorMask(
[email protected]e259eb412012-10-13 05:47:243670 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
3671 state_.color_mask_alpha &&
3672 BoundFramebufferHasColorAttachmentWithAlpha());
[email protected]297ca1c2011-06-20 23:08:463673 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]e259eb412012-10-13 05:47:243674 glDepthMask(state_.depth_mask && have_depth);
[email protected]f731b9462012-10-30 00:35:223675 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
[email protected]297ca1c2011-06-20 23:08:463676 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]e259eb412012-10-13 05:47:243677 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423678 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]e259eb412012-10-13 05:47:243679 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423680 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]f731b9462012-10-30 00:35:223681 EnableDisable(
3682 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3683 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
3684 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
3685 EnableDisable(GL_BLEND, state_.enable_flags.blend);
[email protected]88a61bf2012-10-27 13:00:423686 clear_state_dirty_ = false;
[email protected]297ca1c2011-06-20 23:08:463687 }
3688}
3689
[email protected]1868a342012-11-07 15:56:023690GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]b177ae22011-11-01 03:29:113691 return (offscreen_target_frame_buffer_.get()) ?
3692 offscreen_target_frame_buffer_->id() :
[email protected]1868a342012-11-07 15:56:023693 (surface_ ? surface_->GetBackingFrameBufferObject() : 0);
3694}
3695
3696void GLES2DecoderImpl::RestoreState() const {
[email protected]962bfbe72013-05-24 11:16:143697 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
3698 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:063699 // Restore the Framebuffer first because of bugs in Intel drivers.
3700 // Intel drivers incorrectly clip the viewport settings to
3701 // the size of the current framebuffer object.
3702 RestoreFramebufferBindings();
3703 state_.RestoreState();
3704}
3705
3706void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]1868a342012-11-07 15:56:023707 GLuint service_id = state_.bound_draw_framebuffer ?
3708 state_.bound_draw_framebuffer->service_id() :
3709 GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063710 if (!features().chromium_framebuffer_multisample) {
3711 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
3712 } else {
3713 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
3714 service_id = state_.bound_read_framebuffer ?
3715 state_.bound_read_framebuffer->service_id() :
3716 GetBackbufferServiceId();
3717 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
3718 }
[email protected]70d34263c2013-01-09 00:27:453719 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:063720}
3721
3722void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:103723 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
3724 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:253725 GLenum target = texture->target();
3726 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:063727 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253728 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:063729 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253730 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:063731 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253732 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:063733 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253734 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:063735 RestoreTextureUnitBindings(state_.active_texture_unit);
3736 }
[email protected]70d34263c2013-01-09 00:27:453737}
3738
3739void GLES2DecoderImpl::OnFboChanged() const {
3740 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:513741 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
3742}
3743
3744// Called after the FBO is checked for completeness.
3745void GLES2DecoderImpl::OnUseFramebuffer() const {
3746 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
3747 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:323748 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:513749 glScissor(state_.scissor_x,
3750 state_.scissor_y,
3751 state_.scissor_width,
3752 state_.scissor_height);
3753
3754 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
3755 // it's unclear how this bug works.
3756 glFlush();
3757 }
[email protected]b177ae22011-11-01 03:29:113758}
3759
[email protected]051b1372010-04-12 02:42:083760void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:063761 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:083762 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033763 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:063764 framebuffer = GetFramebuffer(client_id);
3765 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:353766 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153767 LOG(ERROR)
3768 << "glBindFramebuffer: id not generated by glGenFramebuffers";
3769 current_decoder_error_ = error::kGenericError;
3770 return;
[email protected]bf5a8d132011-08-16 08:39:353771 }
3772
[email protected]4d8f0dd2013-03-09 14:37:063773 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:033774 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353775 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:063776 framebuffer = GetFramebuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573777 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103778 group_->GetIdAllocator(id_namespaces::kFramebuffers);
3779 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033780 } else {
[email protected]4d8f0dd2013-03-09 14:37:063781 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:083782 }
[email protected]4d8f0dd2013-03-09 14:37:063783 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083784 }
[email protected]4d8f0dd2013-03-09 14:37:063785 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:303786
3787 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:063788 state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303789 }
3790 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:063791 state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303792 }
[email protected]6217d392010-03-25 22:08:353793
[email protected]88a61bf2012-10-27 13:00:423794 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:463795
[email protected]b177ae22011-11-01 03:29:113796 // If we are rendering to the backbuffer get the FBO id for any simulated
3797 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:063798 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:113799 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:463800 }
[email protected]6217d392010-03-25 22:08:353801
[email protected]051b1372010-04-12 02:42:083802 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:453803 OnFboChanged();
[email protected]86093972010-03-11 00:13:563804}
3805
[email protected]051b1372010-04-12 02:42:083806void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:273807 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:083808 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033809 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:273810 renderbuffer = GetRenderbuffer(client_id);
3811 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:353812 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153813 LOG(ERROR)
3814 << "glBindRenderbuffer: id not generated by glGenRenderbuffers";
3815 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353816 return;
3817 }
3818
[email protected]ee2a79c32013-03-10 03:50:273819 // It's a new id so make a renderbuffer renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:033820 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353821 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:273822 renderbuffer = GetRenderbuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573823 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103824 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
3825 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033826 } else {
[email protected]ee2a79c32013-03-10 03:50:273827 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:083828 }
[email protected]ee2a79c32013-03-10 03:50:273829 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083830 }
[email protected]ee2a79c32013-03-10 03:50:273831 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenerbuffer");
3832 state_.bound_renderbuffer = renderbuffer;
[email protected]051b1372010-04-12 02:42:083833 glBindRenderbufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563834}
3835
[email protected]051b1372010-04-12 02:42:083836void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:493837 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:083838 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033839 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:493840 texture_ref = GetTexture(client_id);
3841 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:353842 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153843 LOG(ERROR) << "glBindTexture: id not generated by glGenTextures";
3844 current_decoder_error_ = error::kGenericError;
3845 return;
[email protected]bf5a8d132011-08-16 08:39:353846 }
3847
[email protected]02965c22013-03-09 02:40:073848 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:033849 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:413850 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:353851 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:493852 texture_ref = GetTexture(client_id);
[email protected]3b1ecc262011-08-03 22:49:573853 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103854 group_->GetIdAllocator(id_namespaces::kTextures);
3855 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033856 }
3857 } else {
[email protected]370eaf12013-05-18 09:19:493858 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:083859 }
[email protected]370eaf12013-05-18 09:19:493860 Texture* texture = texture_ref->texture();
[email protected]ae51d192010-04-27 00:48:033861
[email protected]1958e0e2010-04-22 05:17:153862 // Check the texture exists
3863 // Check that we are not trying to bind it to a different target.
[email protected]02965c22013-03-09 02:40:073864 if (texture->target() != 0 && texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:513865 LOCAL_SET_GL_ERROR(
3866 GL_INVALID_OPERATION,
3867 "glBindTexture", "texture bound to more than 1 target.");
[email protected]1958e0e2010-04-22 05:17:153868 return;
3869 }
[email protected]02965c22013-03-09 02:40:073870 if (texture->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:513871 LOCAL_SET_GL_ERROR(
3872 GL_INVALID_OPERATION,
3873 "glBindTexture", "illegal target for stream texture.");
[email protected]b0af4f52011-09-28 22:04:423874 return;
3875 }
[email protected]02965c22013-03-09 02:40:073876 LogClientServiceForInfo(texture, client_id, "glBindTexture");
3877 if (texture->target() == 0) {
[email protected]370eaf12013-05-18 09:19:493878 texture_manager()->SetTarget(texture_ref, target);
[email protected]a93bb842010-02-16 23:03:473879 }
[email protected]02965c22013-03-09 02:40:073880 glBindTexture(target, texture->service_id());
[email protected]32145a92012-12-17 09:01:593881
[email protected]e259eb412012-10-13 05:47:243882 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:503883 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:473884 switch (target) {
3885 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:493886 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:473887 break;
3888 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:493889 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:473890 break;
[email protected]61eeb33f2011-07-26 15:30:313891 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:493892 unit.bound_texture_external_oes = texture_ref;
[email protected]02965c22013-03-09 02:40:073893 if (texture->IsStreamTexture()) {
[email protected]b0af4f52011-09-28 22:04:423894 DCHECK(stream_texture_manager_);
3895 StreamTexture* stream_tex =
[email protected]02965c22013-03-09 02:40:073896 stream_texture_manager_->LookupStreamTexture(texture->service_id());
[email protected]b0af4f52011-09-28 22:04:423897 if (stream_tex)
3898 stream_tex->Update();
3899 }
[email protected]61eeb33f2011-07-26 15:30:313900 break;
[email protected]e51bdf32011-11-23 22:21:463901 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:493902 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:463903 break;
[email protected]a93bb842010-02-16 23:03:473904 default:
3905 NOTREACHED(); // Validation should prevent us getting here.
3906 break;
3907 }
3908}
3909
[email protected]07f54fcc2009-12-22 02:46:303910void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243911 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:123912 if (index != 0 ||
3913 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:243914 glDisableVertexAttribArray(index);
3915 }
[email protected]07f54fcc2009-12-22 02:46:303916 } else {
[email protected]ab09b612013-03-11 22:11:513917 LOCAL_SET_GL_ERROR(
3918 GL_INVALID_VALUE,
3919 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303920 }
3921}
3922
[email protected]60f22d32012-12-12 00:31:583923void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
3924 GLsizei numAttachments,
3925 const GLenum* attachments) {
[email protected]ed9f9cd2013-02-27 21:12:353926 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:583927 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
3928
3929 // Validates the attachments. If one of them fails
3930 // the whole command fails.
3931 for (GLsizei i = 0; i < numAttachments; ++i) {
3932 if ((framebuffer &&
3933 !validators_->attachment.IsValid(attachments[i])) ||
3934 (!framebuffer &&
3935 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:513936 LOCAL_SET_GL_ERROR_INVALID_ENUM(
3937 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:583938 return;
3939 }
3940 }
3941
3942 // Marks each one of them as not cleared
3943 for (GLsizei i = 0; i < numAttachments; ++i) {
3944 if (framebuffer) {
3945 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
3946 texture_manager(),
3947 attachments[i],
3948 false);
3949 } else {
3950 switch (attachments[i]) {
3951 case GL_COLOR_EXT:
3952 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
3953 break;
3954 case GL_DEPTH_EXT:
3955 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
3956 case GL_STENCIL_EXT:
3957 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
3958 break;
3959 default:
3960 NOTREACHED();
3961 break;
3962 }
3963 }
3964 }
3965
3966 glDiscardFramebufferEXT(target, numAttachments, attachments);
3967}
3968
[email protected]07f54fcc2009-12-22 02:46:303969void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243970 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:303971 glEnableVertexAttribArray(index);
3972 } else {
[email protected]ab09b612013-03-11 22:11:513973 LOCAL_SET_GL_ERROR(
3974 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303975 }
3976}
3977
[email protected]a93bb842010-02-16 23:03:473978void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]370eaf12013-05-18 09:19:493979 TextureRef* texture_ref = GetTextureInfoForTarget(target);
3980 if (!texture_ref ||
3981 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:513982 LOCAL_SET_GL_ERROR(
3983 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:473984 return;
3985 }
[email protected]38c0a972012-05-12 00:48:023986
[email protected]12d95352012-12-14 07:23:543987 if (target == GL_TEXTURE_CUBE_MAP) {
3988 for (int i = 0; i < 6; ++i) {
3989 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:493990 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:513991 LOCAL_SET_GL_ERROR(
3992 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:543993 return;
3994 }
3995 }
3996 } else {
[email protected]370eaf12013-05-18 09:19:493997 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:513998 LOCAL_SET_GL_ERROR(
3999 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544000 return;
4001 }
[email protected]7687479c2012-05-14 23:54:044002 }
4003
[email protected]ab09b612013-03-11 22:11:514004 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194005 // Workaround for Mac driver bug. In the large scheme of things setting
4006 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564007 // hit so there's probably no need to make this conditional. The bug appears
4008 // to be that if the filtering mode is set to something that doesn't require
4009 // mipmaps for rendering, or is never set to something other than the default,
4010 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154011 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194012 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4013 }
[email protected]a93bb842010-02-16 23:03:474014 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154015 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494016 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4017 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194018 }
[email protected]ab09b612013-03-11 22:11:514019 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024020 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494021 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024022 }
[email protected]a93bb842010-02-16 23:03:474023}
4024
[email protected]b273e432010-04-12 17:23:584025bool GLES2DecoderImpl::GetHelper(
4026 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584027 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154028 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4029 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434030 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4031 *num_written = 1;
4032 if (params) {
4033 *params = GL_RGBA; // We don't support other formats.
4034 }
4035 return true;
4036 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4037 *num_written = 1;
4038 if (params) {
4039 *params = GL_UNSIGNED_BYTE; // We don't support other types.
4040 }
4041 return true;
4042 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4043 *num_written = 1;
4044 if (params) {
4045 *params = group_->max_fragment_uniform_vectors();
4046 }
4047 return true;
4048 case GL_MAX_VARYING_VECTORS:
4049 *num_written = 1;
4050 if (params) {
4051 *params = group_->max_varying_vectors();
4052 }
4053 return true;
4054 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4055 *num_written = 1;
4056 if (params) {
4057 *params = group_->max_vertex_uniform_vectors();
4058 }
4059 return true;
[email protected]4e8a5b122010-05-08 22:00:104060 }
[email protected]5cb735d2011-10-13 01:37:234061 }
4062 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244063 case GL_MAX_VIEWPORT_DIMS:
4064 if (offscreen_target_frame_buffer_.get()) {
4065 *num_written = 2;
4066 if (params) {
4067 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4068 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4069 }
4070 return true;
4071 }
[email protected]5cb735d2011-10-13 01:37:234072 return false;
[email protected]84afefa2011-10-19 21:45:534073 case GL_MAX_SAMPLES:
4074 *num_written = 1;
4075 if (params) {
4076 params[0] = renderbuffer_manager()->max_samples();
4077 }
4078 return true;
4079 case GL_MAX_RENDERBUFFER_SIZE:
4080 *num_written = 1;
4081 if (params) {
4082 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4083 }
4084 return true;
[email protected]5cb735d2011-10-13 01:37:234085 case GL_MAX_TEXTURE_SIZE:
4086 *num_written = 1;
4087 if (params) {
4088 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4089 }
4090 return true;
4091 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4092 *num_written = 1;
4093 if (params) {
4094 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4095 }
4096 return true;
[email protected]2f143d482013-03-14 18:04:494097 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4098 *num_written = 1;
4099 if (params) {
4100 params[0] = group_->max_color_attachments();
4101 }
4102 return true;
4103 case GL_MAX_DRAW_BUFFERS_ARB:
4104 *num_written = 1;
4105 if (params) {
4106 params[0] = group_->max_draw_buffers();
4107 }
4108 return true;
[email protected]297ca1c2011-06-20 23:08:464109 case GL_ALPHA_BITS:
4110 *num_written = 1;
4111 if (params) {
4112 GLint v = 0;
4113 glGetIntegerv(GL_ALPHA_BITS, &v);
4114 params[0] = BoundFramebufferHasColorAttachmentWithAlpha() ? v : 0;
4115 }
4116 return true;
4117 case GL_DEPTH_BITS:
4118 *num_written = 1;
4119 if (params) {
4120 GLint v = 0;
4121 glGetIntegerv(GL_DEPTH_BITS, &v);
4122 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4123 }
4124 return true;
4125 case GL_STENCIL_BITS:
4126 *num_written = 1;
4127 if (params) {
4128 GLint v = 0;
4129 glGetIntegerv(GL_STENCIL_BITS, &v);
4130 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4131 }
4132 return true;
[email protected]656dcaad2010-05-07 17:18:374133 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114134 *num_written = validators_->compressed_texture_format.GetValues().size();
4135 if (params) {
4136 for (GLint ii = 0; ii < *num_written; ++ii) {
4137 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4138 }
4139 }
[email protected]656dcaad2010-05-07 17:18:374140 return true;
[email protected]b273e432010-04-12 17:23:584141 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4142 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104143 if (params) {
[email protected]302ce6d2011-07-07 23:28:114144 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104145 }
[email protected]b273e432010-04-12 17:23:584146 return true;
4147 case GL_NUM_SHADER_BINARY_FORMATS:
4148 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104149 if (params) {
[email protected]302ce6d2011-07-07 23:28:114150 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104151 }
[email protected]b273e432010-04-12 17:23:584152 return true;
4153 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114154 *num_written = validators_->shader_binary_format.GetValues().size();
4155 if (params) {
4156 for (GLint ii = 0; ii < *num_written; ++ii) {
4157 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4158 }
4159 }
4160 return true;
[email protected]b273e432010-04-12 17:23:584161 case GL_SHADER_COMPILER:
4162 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104163 if (params) {
4164 *params = GL_TRUE;
4165 }
[email protected]b273e432010-04-12 17:23:584166 return true;
[email protected]6b8cf1a2010-05-06 16:13:584167 case GL_ARRAY_BUFFER_BINDING:
4168 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104169 if (params) {
[email protected]e259eb412012-10-13 05:47:244170 if (state_.bound_array_buffer) {
[email protected]4e8a5b122010-05-08 22:00:104171 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244172 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104173 &client_id);
4174 *params = client_id;
4175 } else {
4176 *params = 0;
4177 }
[email protected]6b8cf1a2010-05-06 16:13:584178 }
4179 return true;
4180 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4181 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104182 if (params) {
[email protected]e259eb412012-10-13 05:47:244183 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104184 GLuint client_id = 0;
4185 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254186 state_.vertex_attrib_manager->element_array_buffer()->
4187 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104188 *params = client_id;
4189 } else {
4190 *params = 0;
4191 }
[email protected]6b8cf1a2010-05-06 16:13:584192 }
4193 return true;
4194 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304195 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584196 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104197 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354198 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454199 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204200 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104201 GLuint client_id = 0;
4202 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204203 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304204 *params = client_id;
4205 } else {
4206 *params = 0;
4207 }
4208 }
4209 return true;
[email protected]ebfb73c2012-08-15 02:37:454210 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304211 *num_written = 1;
4212 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354213 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454214 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204215 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304216 GLuint client_id = 0;
4217 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204218 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104219 *params = client_id;
4220 } else {
4221 *params = 0;
4222 }
[email protected]6b8cf1a2010-05-06 16:13:584223 }
4224 return true;
4225 case GL_RENDERBUFFER_BINDING:
4226 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104227 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354228 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204229 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4230 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104231 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104232 } else {
4233 *params = 0;
4234 }
[email protected]6b8cf1a2010-05-06 16:13:584235 }
4236 return true;
4237 case GL_CURRENT_PROGRAM:
4238 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104239 if (params) {
[email protected]e259eb412012-10-13 05:47:244240 if (state_.current_program) {
[email protected]4e8a5b122010-05-08 22:00:104241 GLuint client_id = 0;
4242 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244243 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104244 *params = client_id;
4245 } else {
4246 *params = 0;
4247 }
[email protected]6b8cf1a2010-05-06 16:13:584248 }
4249 return true;
[email protected]bf835842012-11-19 15:21:514250 case GL_VERTEX_ARRAY_BINDING_OES:
4251 *num_written = 1;
4252 if (params) {
4253 if (state_.vertex_attrib_manager != default_vertex_attrib_manager_) {
4254 GLuint client_id = 0;
4255 vertex_array_manager_->GetClientId(
4256 state_.vertex_attrib_manager->service_id(), &client_id);
4257 *params = client_id;
4258 } else {
4259 *params = 0;
4260 }
4261 }
4262 return true;
[email protected]4e8a5b122010-05-08 22:00:104263 case GL_TEXTURE_BINDING_2D:
4264 *num_written = 1;
4265 if (params) {
[email protected]e259eb412012-10-13 05:47:244266 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]6b8cf1a2010-05-06 16:13:584267 if (unit.bound_texture_2d) {
[email protected]62e65f02013-05-29 22:28:104268 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584269 } else {
4270 *params = 0;
4271 }
[email protected]6b8cf1a2010-05-06 16:13:584272 }
[email protected]4e8a5b122010-05-08 22:00:104273 return true;
4274 case GL_TEXTURE_BINDING_CUBE_MAP:
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]6b8cf1a2010-05-06 16:13:584278 if (unit.bound_texture_cube_map) {
[email protected]62e65f02013-05-29 22:28:104279 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584280 } else {
4281 *params = 0;
4282 }
[email protected]6b8cf1a2010-05-06 16:13:584283 }
[email protected]4e8a5b122010-05-08 22:00:104284 return true;
[email protected]61eeb33f2011-07-26 15:30:314285 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4286 *num_written = 1;
4287 if (params) {
[email protected]e259eb412012-10-13 05:47:244288 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]61eeb33f2011-07-26 15:30:314289 if (unit.bound_texture_external_oes) {
[email protected]62e65f02013-05-29 22:28:104290 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314291 } else {
4292 *params = 0;
4293 }
4294 }
4295 return true;
[email protected]e51bdf32011-11-23 22:21:464296 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4297 *num_written = 1;
4298 if (params) {
[email protected]e259eb412012-10-13 05:47:244299 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]e51bdf32011-11-23 22:21:464300 if (unit.bound_texture_rectangle_arb) {
[email protected]62e65f02013-05-29 22:28:104301 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464302 } else {
4303 *params = 0;
4304 }
4305 }
4306 return true;
[email protected]6c75c712012-06-19 15:43:174307 case GL_UNPACK_FLIP_Y_CHROMIUM:
4308 *num_written = 1;
4309 if (params) {
4310 params[0] = unpack_flip_y_;
4311 }
4312 return true;
4313 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4314 *num_written = 1;
4315 if (params) {
4316 params[0] = unpack_premultiply_alpha_;
4317 }
4318 return true;
4319 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4320 *num_written = 1;
4321 if (params) {
4322 params[0] = unpack_unpremultiply_alpha_;
4323 }
4324 return true;
[email protected]b273e432010-04-12 17:23:584325 default:
[email protected]2f143d482013-03-14 18:04:494326 if (pname >= GL_DRAW_BUFFER0_ARB &&
4327 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4328 *num_written = 1;
4329 if (params) {
4330 Framebuffer* framebuffer =
4331 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4332 if (framebuffer) {
4333 params[0] = framebuffer->GetDrawBuffer(pname);
4334 } else { // backbuffer
4335 if (pname == GL_DRAW_BUFFER0_ARB)
4336 params[0] = group_->draw_buffer();
4337 else
4338 params[0] = GL_NONE;
4339 }
4340 }
4341 return true;
4342 }
[email protected]4e8a5b122010-05-08 22:00:104343 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534344 return false;
[email protected]b273e432010-04-12 17:23:584345 }
4346}
4347
[email protected]4e8a5b122010-05-08 22:00:104348bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4349 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264350 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534351 return true;
4352 }
[email protected]4e8a5b122010-05-08 22:00:104353 return GetHelper(pname, NULL, num_values);
4354}
4355
[email protected]b273e432010-04-12 17:23:584356void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4357 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104358 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534359 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554360 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264361 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534362 GetHelper(pname, values.get(), &num_written);
4363 }
[email protected]b273e432010-04-12 17:23:584364 for (GLsizei ii = 0; ii < num_written; ++ii) {
4365 params[ii] = static_cast<GLboolean>(values[ii]);
4366 }
4367 } else {
4368 glGetBooleanv(pname, params);
4369 }
4370}
4371
4372void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4373 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104374 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264375 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534376 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554377 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534378 GetHelper(pname, values.get(), &num_written);
4379 for (GLsizei ii = 0; ii < num_written; ++ii) {
4380 params[ii] = static_cast<GLfloat>(values[ii]);
4381 }
4382 } else {
4383 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584384 }
[email protected]b273e432010-04-12 17:23:584385 }
4386}
4387
4388void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4389 DCHECK(params);
4390 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264391 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534392 !GetHelper(pname, params, &num_written)) {
[email protected]b273e432010-04-12 17:23:584393 glGetIntegerv(pname, params);
4394 }
4395}
4396
[email protected]a0c3e972010-04-21 00:49:134397void GLES2DecoderImpl::DoGetProgramiv(
4398 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424399 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4400 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134401 return;
4402 }
[email protected]df37b9932013-03-08 05:21:424403 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134404}
4405
[email protected]17cfbe0e2013-03-07 01:26:084406void GLES2DecoderImpl::DoGetBufferParameteriv(
4407 GLenum target, GLenum pname, GLint* params) {
4408 Buffer* buffer = GetBufferInfoForTarget(target);
4409 if (!buffer) {
[email protected]ab09b612013-03-11 22:11:514410 LOCAL_SET_GL_ERROR(
[email protected]17cfbe0e2013-03-07 01:26:084411 GL_INVALID_OPERATION, "glGetBufferParameteriv",
4412 "no buffer bound for target");
4413 return;
4414 }
4415 switch (pname) {
4416 case GL_BUFFER_SIZE:
4417 *params = buffer->size();
4418 break;
4419 case GL_BUFFER_USAGE:
4420 *params = buffer->usage();
4421 break;
4422 default:
4423 NOTREACHED();
4424 }
4425}
4426
[email protected]258a3313f2011-10-18 20:13:574427void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424428 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574429 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514430 LOCAL_SET_GL_ERROR(
4431 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574432 return;
4433 }
[email protected]68dcb1f2012-04-07 00:14:564434 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514435 LOCAL_SET_GL_ERROR(
4436 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564437 return;
4438 }
4439 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514440 LOCAL_SET_GL_ERROR(
4441 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564442 return;
4443 }
[email protected]df37b9932013-03-08 05:21:424444 Program* program = GetProgramInfoNotShader(
4445 program_id, "glBindAttribLocation");
4446 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574447 return;
[email protected]558847a2010-03-24 07:02:544448 }
[email protected]df37b9932013-03-08 05:21:424449 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
4450 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574451}
4452
4453error::Error GLES2DecoderImpl::HandleBindAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:354454 uint32 immediate_data_size, const cmds::BindAttribLocation& c) {
[email protected]258a3313f2011-10-18 20:13:574455 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544456 GLuint index = static_cast<GLuint>(c.index);
4457 uint32 name_size = c.data_size;
4458 const char* name = GetSharedMemoryAs<const char*>(
4459 c.name_shm_id, c.name_shm_offset, name_size);
4460 if (name == NULL) {
4461 return error::kOutOfBounds;
4462 }
4463 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574464 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544465 return error::kNoError;
4466}
4467
4468error::Error GLES2DecoderImpl::HandleBindAttribLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:354469 uint32 immediate_data_size, const cmds::BindAttribLocationImmediate& c) {
[email protected]6b8cf1a2010-05-06 16:13:584470 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544471 GLuint index = static_cast<GLuint>(c.index);
4472 uint32 name_size = c.data_size;
4473 const char* name = GetImmediateDataAs<const char*>(
4474 c, name_size, immediate_data_size);
4475 if (name == NULL) {
4476 return error::kOutOfBounds;
4477 }
4478 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574479 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544480 return error::kNoError;
4481}
4482
4483error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:354484 uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) {
[email protected]6b8cf1a2010-05-06 16:13:584485 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544486 GLuint index = static_cast<GLuint>(c.index);
4487 Bucket* bucket = GetBucket(c.name_bucket_id);
4488 if (!bucket || bucket->size() == 0) {
4489 return error::kInvalidArguments;
4490 }
4491 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184492 if (!bucket->GetAsString(&name_str)) {
4493 return error::kInvalidArguments;
4494 }
[email protected]258a3313f2011-10-18 20:13:574495 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544496 return error::kNoError;
4497}
4498
[email protected]2be6abf32012-06-26 00:28:334499void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424500 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334501 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514502 LOCAL_SET_GL_ERROR(
4503 GL_INVALID_VALUE,
4504 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334505 return;
4506 }
4507 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514508 LOCAL_SET_GL_ERROR(
4509 GL_INVALID_OPERATION,
4510 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334511 return;
4512 }
4513 if (location < 0 || static_cast<uint32>(location) >=
4514 (group_->max_fragment_uniform_vectors() +
4515 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514516 LOCAL_SET_GL_ERROR(
4517 GL_INVALID_VALUE,
4518 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334519 return;
4520 }
[email protected]df37b9932013-03-08 05:21:424521 Program* program = GetProgramInfoNotShader(
4522 program_id, "glBindUniformLocationCHROMIUM");
4523 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334524 return;
4525 }
[email protected]df37b9932013-03-08 05:21:424526 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514527 LOCAL_SET_GL_ERROR(
4528 GL_INVALID_VALUE,
4529 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334530 }
4531}
4532
4533error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354534 uint32 immediate_data_size, const cmds::BindUniformLocationCHROMIUM& c) {
[email protected]2be6abf32012-06-26 00:28:334535 GLuint program = static_cast<GLuint>(c.program);
4536 GLint location = static_cast<GLint>(c.location);
4537 uint32 name_size = c.data_size;
4538 const char* name = GetSharedMemoryAs<const char*>(
4539 c.name_shm_id, c.name_shm_offset, name_size);
4540 if (name == NULL) {
4541 return error::kOutOfBounds;
4542 }
4543 String name_str(name, name_size);
4544 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4545 return error::kNoError;
4546}
4547
4548error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMImmediate(
4549 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354550 const cmds::BindUniformLocationCHROMIUMImmediate& c) {
[email protected]2be6abf32012-06-26 00:28:334551 GLuint program = static_cast<GLuint>(c.program);
4552 GLint location = static_cast<GLint>(c.location);
4553 uint32 name_size = c.data_size;
4554 const char* name = GetImmediateDataAs<const char*>(
4555 c, name_size, immediate_data_size);
4556 if (name == NULL) {
4557 return error::kOutOfBounds;
4558 }
4559 String name_str(name, name_size);
4560 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4561 return error::kNoError;
4562}
4563
4564error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4565 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354566 const cmds::BindUniformLocationCHROMIUMBucket& c) {
[email protected]2be6abf32012-06-26 00:28:334567 GLuint program = static_cast<GLuint>(c.program);
4568 GLint location = static_cast<GLint>(c.location);
4569 Bucket* bucket = GetBucket(c.name_bucket_id);
4570 if (!bucket || bucket->size() == 0) {
4571 return error::kInvalidArguments;
4572 }
4573 std::string name_str;
4574 if (!bucket->GetAsString(&name_str)) {
4575 return error::kInvalidArguments;
4576 }
4577 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4578 return error::kNoError;
4579}
4580
[email protected]f7a64ee2010-02-01 22:24:144581error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ed9f9cd2013-02-27 21:12:354582 uint32 immediate_data_size, const cmds::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034583 GLuint client_id = c.shader;
4584 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424585 Shader* shader = GetShader(client_id);
4586 if (shader) {
4587 if (!shader->IsDeleted()) {
4588 glDeleteShader(shader->service_id());
4589 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144590 }
[email protected]ae51d192010-04-27 00:48:034591 } else {
[email protected]ab09b612013-03-11 22:11:514592 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034593 }
[email protected]96449d2c2009-11-25 00:01:324594 }
[email protected]f7a64ee2010-02-01 22:24:144595 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324596}
4597
[email protected]f7a64ee2010-02-01 22:24:144598error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ed9f9cd2013-02-27 21:12:354599 uint32 immediate_data_size, const cmds::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034600 GLuint client_id = c.program;
4601 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424602 Program* program = GetProgram(client_id);
4603 if (program) {
4604 if (!program->IsDeleted()) {
4605 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144606 }
[email protected]ae51d192010-04-27 00:48:034607 } else {
[email protected]ab09b612013-03-11 22:11:514608 LOCAL_SET_GL_ERROR(
4609 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034610 }
[email protected]96449d2c2009-11-25 00:01:324611 }
[email protected]f7a64ee2010-02-01 22:24:144612 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324613}
4614
[email protected]269200b12010-11-18 22:53:064615void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104616 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574617 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104618 for (GLsizei ii = 0; ii < n; ++ii) {
4619 id_allocator->FreeID(ids[ii]);
4620 }
4621}
4622
[email protected]269200b12010-11-18 22:53:064623error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354624 uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104625 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4626 GLsizei n = static_cast<GLsizei>(c.n);
4627 uint32 data_size;
4628 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4629 return error::kOutOfBounds;
4630 }
4631 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4632 c.ids_shm_id, c.ids_shm_offset, data_size);
4633 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514634 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104635 return error::kNoError;
4636 }
4637 if (ids == NULL) {
4638 return error::kOutOfBounds;
4639 }
[email protected]269200b12010-11-18 22:53:064640 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104641 return error::kNoError;
4642}
4643
[email protected]269200b12010-11-18 22:53:064644void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104645 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574646 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104647 if (id_offset == 0) {
4648 for (GLsizei ii = 0; ii < n; ++ii) {
4649 ids[ii] = id_allocator->AllocateID();
4650 }
4651 } else {
4652 for (GLsizei ii = 0; ii < n; ++ii) {
4653 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4654 id_offset = ids[ii] + 1;
4655 }
4656 }
4657}
4658
[email protected]269200b12010-11-18 22:53:064659error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354660 uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104661 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4662 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4663 GLsizei n = static_cast<GLsizei>(c.n);
4664 uint32 data_size;
4665 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4666 return error::kOutOfBounds;
4667 }
4668 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4669 c.ids_shm_id, c.ids_shm_offset, data_size);
4670 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514671 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104672 return error::kNoError;
4673 }
4674 if (ids == NULL) {
4675 return error::kOutOfBounds;
4676 }
[email protected]269200b12010-11-18 22:53:064677 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104678 return error::kNoError;
4679}
4680
[email protected]269200b12010-11-18 22:53:064681void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104682 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574683 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104684 for (GLsizei ii = 0; ii < n; ++ii) {
4685 if (!id_allocator->MarkAsUsed(ids[ii])) {
4686 for (GLsizei jj = 0; jj < ii; ++jj) {
4687 id_allocator->FreeID(ids[jj]);
4688 }
[email protected]ab09b612013-03-11 22:11:514689 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:434690 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4691 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104692 return;
4693 }
4694 }
4695}
4696
[email protected]269200b12010-11-18 22:53:064697error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354698 uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104699 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4700 GLsizei n = static_cast<GLsizei>(c.n);
4701 uint32 data_size;
4702 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4703 return error::kOutOfBounds;
4704 }
4705 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4706 c.ids_shm_id, c.ids_shm_offset, data_size);
4707 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514708 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104709 return error::kNoError;
4710 }
4711 if (ids == NULL) {
4712 return error::kOutOfBounds;
4713 }
[email protected]269200b12010-11-18 22:53:064714 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104715 return error::kNoError;
4716}
4717
[email protected]a7266a92012-06-28 02:11:084718error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444719 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204720 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]e259eb412012-10-13 05:47:244721 UNSHIPPED_TRACE_EVENT_INSTANT2(
4722 "test_gpu", "DoClear",
[email protected]c76faea2013-03-26 07:42:424723 TRACE_EVENT_SCOPE_THREAD,
[email protected]e259eb412012-10-13 05:47:244724 "red", state_.color_clear_red,
4725 "green", state_.color_clear_green);
[email protected]297ca1c2011-06-20 23:08:464726 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:274727 glClear(mask);
4728 }
[email protected]a7266a92012-06-28 02:11:084729 return error::kNoError;
4730}
4731
[email protected]36cef8ce2010-03-16 07:34:454732void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4733 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:034734 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:064735 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4736 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514737 LOCAL_SET_GL_ERROR(
4738 GL_INVALID_OPERATION,
4739 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454740 return;
4741 }
[email protected]ae51d192010-04-27 00:48:034742 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:274743 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:034744 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:274745 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
4746 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514747 LOCAL_SET_GL_ERROR(
4748 GL_INVALID_OPERATION,
4749 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:034750 return;
4751 }
[email protected]ee2a79c32013-03-10 03:50:274752 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:034753 }
[email protected]ab09b612013-03-11 22:11:514754 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:034755 glFramebufferRenderbufferEXT(
4756 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:514757 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:264758 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:274759 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:284760 }
[email protected]4d8f0dd2013-03-09 14:37:064761 if (framebuffer == state_.bound_draw_framebuffer) {
[email protected]88a61bf2012-10-27 13:00:424762 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464763 }
[email protected]81fc9d02013-03-14 23:53:324764 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:284765}
4766
[email protected]3a2e7c7b2010-08-06 01:12:284767void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464768 if (SetCapabilityState(cap, false)) {
4769 glDisable(cap);
4770 }
[email protected]3a2e7c7b2010-08-06 01:12:284771}
4772
4773void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464774 if (SetCapabilityState(cap, true)) {
4775 glEnable(cap);
4776 }
[email protected]3a2e7c7b2010-08-06 01:12:284777}
4778
[email protected]88a61bf2012-10-27 13:00:424779void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4780 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4781 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4782 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:284783}
4784
[email protected]88a61bf2012-10-27 13:00:424785void GLES2DecoderImpl::DoHint(GLenum target, GLenum mode) {
4786 switch (target) {
4787 case GL_GENERATE_MIPMAP_HINT:
4788 state_.hint_generate_mipmap = mode;
4789 break;
4790 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4791 state_.hint_fragment_shader_derivative = mode;
4792 break;
4793 default:
4794 NOTREACHED();
4795 }
4796 glHint(target, mode);
4797}
4798
[email protected]b04e24c2013-01-08 18:35:254799void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:424800 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
4801 state_.sample_coverage_invert = (invert != 0);
4802 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:284803}
4804
[email protected]0d6bfdc2011-11-02 01:32:204805// Assumes framebuffer is complete.
4806void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:064807 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304808 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204809 // bind this to the DRAW point, clear then bind back to READ
4810 // TODO(gman): I don't think there is any guarantee that an FBO that
4811 // is complete on the READ attachment will be complete as a DRAW
4812 // attachment.
4813 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:064814 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:304815 }
[email protected]3a2e7c7b2010-08-06 01:12:284816 GLbitfield clear_bits = 0;
[email protected]4d8f0dd2013-03-09 14:37:064817 if (framebuffer->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
[email protected]297ca1c2011-06-20 23:08:464818 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:204819 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:464820 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:064821 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
4822 1.0f);
[email protected]3a2e7c7b2010-08-06 01:12:284823 glColorMask(true, true, true, true);
4824 clear_bits |= GL_COLOR_BUFFER_BIT;
4825 }
4826
[email protected]4d8f0dd2013-03-09 14:37:064827 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
4828 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284829 glClearStencil(0);
4830 glStencilMask(-1);
4831 clear_bits |= GL_STENCIL_BUFFER_BIT;
4832 }
4833
[email protected]4d8f0dd2013-03-09 14:37:064834 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
4835 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284836 glClearDepth(1.0f);
4837 glDepthMask(true);
4838 clear_bits |= GL_DEPTH_BUFFER_BIT;
4839 }
4840
4841 glDisable(GL_SCISSOR_TEST);
4842 glClear(clear_bits);
4843
[email protected]968351b2011-12-20 08:26:514844 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:064845 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:284846
[email protected]c007aa02010-09-02 22:22:404847 RestoreClearState();
4848
4849 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:064850 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
4851 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:484852 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:064853 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
4854 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:484855 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:404856 }
4857}
4858
4859void GLES2DecoderImpl::RestoreClearState() {
[email protected]88a61bf2012-10-27 13:00:424860 clear_state_dirty_ = true;
[email protected]e259eb412012-10-13 05:47:244861 glClearColor(
4862 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
4863 state_.color_clear_alpha);
4864 glClearStencil(state_.stencil_clear);
4865 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:224866 if (state_.enable_flags.scissor_test) {
[email protected]3a2e7c7b2010-08-06 01:12:284867 glEnable(GL_SCISSOR_TEST);
4868 }
[email protected]36cef8ce2010-03-16 07:34:454869}
4870
4871GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:354872 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:304873 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:204874 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:454875 return GL_FRAMEBUFFER_COMPLETE;
4876 }
[email protected]0d6bfdc2011-11-02 01:32:204877 GLenum completeness = framebuffer->IsPossiblyComplete();
4878 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
4879 return completeness;
4880 }
[email protected]73276522012-11-09 05:50:204881 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:454882}
4883
4884void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:034885 GLenum target, GLenum attachment, GLenum textarget,
4886 GLuint client_texture_id, GLint level) {
[email protected]4d8f0dd2013-03-09 14:37:064887 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4888 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514889 LOCAL_SET_GL_ERROR(
4890 GL_INVALID_OPERATION,
4891 "glFramebufferTexture2D", "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:454892 return;
4893 }
[email protected]ae51d192010-04-27 00:48:034894 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:494895 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:034896 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:494897 texture_ref = GetTexture(client_texture_id);
4898 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:514899 LOCAL_SET_GL_ERROR(
4900 GL_INVALID_OPERATION,
[email protected]370eaf12013-05-18 09:19:494901 "glFramebufferTexture2D", "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:034902 return;
4903 }
[email protected]370eaf12013-05-18 09:19:494904 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:034905 }
[email protected]0d6bfdc2011-11-02 01:32:204906
[email protected]80eb6b52012-01-19 00:14:414907 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:514908 LOCAL_SET_GL_ERROR(
4909 GL_INVALID_VALUE,
4910 "glFramebufferTexture2D", "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:204911 return;
4912 }
4913
[email protected]ab09b612013-03-11 22:11:514914 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferTexture2D");
[email protected]ae51d192010-04-27 00:48:034915 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
[email protected]ab09b612013-03-11 22:11:514916 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferTexture2D");
[email protected]9edc6b22010-12-23 02:00:264917 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494918 framebuffer->AttachTexture(attachment, texture_ref, textarget, level);
[email protected]3a2e7c7b2010-08-06 01:12:284919 }
[email protected]4d8f0dd2013-03-09 14:37:064920 if (framebuffer == state_.bound_draw_framebuffer) {
[email protected]88a61bf2012-10-27 13:00:424921 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:464922 }
[email protected]81fc9d02013-03-14 23:53:324923 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:454924}
4925
4926void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
4927 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:064928 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4929 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514930 LOCAL_SET_GL_ERROR(
4931 GL_INVALID_OPERATION,
4932 "glFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454933 return;
4934 }
[email protected]74c1ec42010-08-12 01:55:574935 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:104936 const Framebuffer::Attachment* attachment_object =
4937 framebuffer->GetAttachment(attachment);
4938 *params = attachment_object ? attachment_object->object_name() : 0;
4939 } else {
4940 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:574941 }
[email protected]36cef8ce2010-03-16 07:34:454942}
4943
4944void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
4945 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:354946 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204947 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4948 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514949 LOCAL_SET_GL_ERROR(
4950 GL_INVALID_OPERATION,
4951 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454952 return;
4953 }
[email protected]3a03a8f2011-03-19 00:51:274954 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434955 case GL_RENDERBUFFER_INTERNAL_FORMAT:
4956 *params = renderbuffer->internal_format();
4957 break;
4958 case GL_RENDERBUFFER_WIDTH:
4959 *params = renderbuffer->width();
4960 break;
4961 case GL_RENDERBUFFER_HEIGHT:
4962 *params = renderbuffer->height();
4963 break;
4964 default:
4965 glGetRenderbufferParameterivEXT(target, pname, params);
4966 break;
[email protected]b71f52c2010-06-18 22:20:204967 }
[email protected]36cef8ce2010-03-16 07:34:454968}
4969
[email protected]8e3e0662010-08-23 18:46:304970void GLES2DecoderImpl::DoBlitFramebufferEXT(
4971 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
4972 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
4973 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:444974 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]62e155e2012-10-23 22:43:154975 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:514976 LOCAL_SET_GL_ERROR(
4977 GL_INVALID_OPERATION,
4978 "glBlitFramebufferEXT", "function not available");
[email protected]8e3e0662010-08-23 18:46:304979 }
[email protected]0c16343f2013-03-08 20:40:164980
4981 if (!CheckBoundFramebuffersValid("glBlitFramebufferEXT")) {
4982 return;
4983 }
4984
[email protected]d058bca2012-11-26 10:27:264985 glDisable(GL_SCISSOR_TEST);
[email protected]5094b0f2010-11-09 19:45:244986 if (IsAngle()) {
4987 glBlitFramebufferANGLE(
4988 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
4989 } else {
4990 glBlitFramebufferEXT(
4991 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
4992 }
[email protected]d058bca2012-11-26 10:27:264993 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
[email protected]c76faea2013-03-26 07:42:424994 UNSHIPPED_TRACE_EVENT_INSTANT1("test_gpu", "DoBlit", TRACE_EVENT_SCOPE_THREAD,
4995 "width", srcX1 - srcX0);
[email protected]8e3e0662010-08-23 18:46:304996}
4997
4998void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
4999 GLenum target, GLsizei samples, GLenum internalformat,
5000 GLsizei width, GLsizei height) {
[email protected]62e155e2012-10-23 22:43:155001 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:515002 LOCAL_SET_GL_ERROR(
5003 GL_INVALID_OPERATION,
5004 "glRenderbufferStorageMultisample", "function not available");
[email protected]8e3e0662010-08-23 18:46:305005 return;
5006 }
[email protected]8e3e0662010-08-23 18:46:305007
[email protected]ed9f9cd2013-02-27 21:12:355008 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205009 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5010 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515011 LOCAL_SET_GL_ERROR(
5012 GL_INVALID_OPERATION,
5013 "glRenderbufferStorageMultisample", "no renderbuffer bound");
[email protected]0d6bfdc2011-11-02 01:32:205014 return;
5015 }
5016
[email protected]84afefa2011-10-19 21:45:535017 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515018 LOCAL_SET_GL_ERROR(
5019 GL_INVALID_VALUE,
5020 "glRenderbufferStorageMultisample", "samples too large");
[email protected]84afefa2011-10-19 21:45:535021 return;
5022 }
5023
5024 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5025 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515026 LOCAL_SET_GL_ERROR(
5027 GL_INVALID_VALUE,
5028 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535029 return;
5030 }
5031
[email protected]7989c9e2013-01-23 06:39:265032 uint32 estimated_size = 0;
5033 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
5034 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515035 LOCAL_SET_GL_ERROR(
5036 GL_OUT_OF_MEMORY,
5037 "glRenderbufferStorageMultsample", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265038 return;
[email protected]8e3e0662010-08-23 18:46:305039 }
5040
[email protected]7989c9e2013-01-23 06:39:265041 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515042 LOCAL_SET_GL_ERROR(
5043 GL_OUT_OF_MEMORY,
5044 "glRenderbufferStorageMultsample", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265045 return;
5046 }
5047
5048 GLenum impl_format = RenderbufferManager::
5049 InternalRenderbufferFormatToImplFormat(internalformat);
[email protected]ab09b612013-03-11 22:11:515050 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisample");
[email protected]866b91c52011-03-23 14:38:085051 if (IsAngle()) {
5052 glRenderbufferStorageMultisampleANGLE(
5053 target, samples, impl_format, width, height);
5054 } else {
5055 glRenderbufferStorageMultisampleEXT(
5056 target, samples, impl_format, width, height);
5057 }
[email protected]ab09b612013-03-11 22:11:515058 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisample");
[email protected]9edc6b22010-12-23 02:00:265059 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515060 // TODO(gman): If renderbuffers tracked which framebuffers they were
5061 // attached to we could just mark those framebuffers as not complete.
5062 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205063 renderbuffer_manager()->SetInfo(
5064 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265065 }
[email protected]8e3e0662010-08-23 18:46:305066}
5067
[email protected]36cef8ce2010-03-16 07:34:455068void GLES2DecoderImpl::DoRenderbufferStorage(
5069 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355070 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205071 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5072 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515073 LOCAL_SET_GL_ERROR(
5074 GL_INVALID_OPERATION,
5075 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455076 return;
5077 }
[email protected]876f6fee2010-08-02 23:10:325078
[email protected]84afefa2011-10-19 21:45:535079 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5080 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515081 LOCAL_SET_GL_ERROR(
5082 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535083 return;
5084 }
5085
[email protected]7989c9e2013-01-23 06:39:265086 uint32 estimated_size = 0;
5087 if (!RenderbufferManager::ComputeEstimatedRenderbufferSize(
5088 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515089 LOCAL_SET_GL_ERROR(
5090 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265091 return;
5092 }
5093
5094 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515095 LOCAL_SET_GL_ERROR(
5096 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265097 return;
[email protected]b71f52c2010-06-18 22:20:205098 }
[email protected]876f6fee2010-08-02 23:10:325099
[email protected]ab09b612013-03-11 22:11:515100 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265101 glRenderbufferStorageEXT(
5102 target, RenderbufferManager::
5103 InternalRenderbufferFormatToImplFormat(internalformat),
5104 width, height);
[email protected]ab09b612013-03-11 22:11:515105 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265106 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515107 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5108 // we could just mark those framebuffers as not complete.
5109 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205110 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265111 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265112 }
[email protected]36cef8ce2010-03-16 07:34:455113}
5114
[email protected]df37b9932013-03-08 05:21:425115void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385116 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425117 Program* program = GetProgramInfoNotShader(
5118 program_id, "glLinkProgram");
5119 if (!program) {
[email protected]a93bb842010-02-16 23:03:475120 return;
5121 }
[email protected]05afda12011-01-20 00:17:345122
[email protected]df37b9932013-03-08 05:21:425123 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395124 ShaderTranslator* vertex_translator = NULL;
5125 ShaderTranslator* fragment_translator = NULL;
5126 if (use_shader_translator_) {
5127 vertex_translator = vertex_translator_;
5128 fragment_translator = fragment_translator_;
5129 }
[email protected]df37b9932013-03-08 05:21:425130 if (program->Link(shader_manager(),
[email protected]65dfc602012-07-23 20:39:395131 vertex_translator,
5132 fragment_translator,
[email protected]e3932abb2013-03-13 00:01:375133 feature_info_,
5134 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425135 if (program == state_.current_program.get()) {
[email protected]62e155e2012-10-23 22:43:155136 if (workarounds().use_current_program_after_successful_link) {
[email protected]df37b9932013-03-08 05:21:425137 glUseProgram(program->service_id());
[email protected]c2a3caf12012-10-23 19:32:005138 }
[email protected]df37b9932013-03-08 05:21:425139 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545140 }
5141 }
[email protected]07f54fcc2009-12-22 02:46:305142};
5143
[email protected]3916c97e2010-02-25 03:20:505144void GLES2DecoderImpl::DoTexParameterf(
5145 GLenum target, GLenum pname, GLfloat param) {
[email protected]370eaf12013-05-18 09:19:495146 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:075147 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515148 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245149 return;
[email protected]07f54fcc2009-12-22 02:46:305150 }
[email protected]cbb22e42011-05-12 23:36:245151
[email protected]02965c22013-03-09 02:40:075152 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505153 "glTexParameterf", GetErrorState(), texture, pname,
5154 static_cast<GLint>(param));
[email protected]07f54fcc2009-12-22 02:46:305155}
5156
[email protected]3916c97e2010-02-25 03:20:505157void GLES2DecoderImpl::DoTexParameteri(
5158 GLenum target, GLenum pname, GLint param) {
[email protected]370eaf12013-05-18 09:19:495159 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:075160 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515161 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245162 return;
[email protected]3916c97e2010-02-25 03:20:505163 }
[email protected]cbb22e42011-05-12 23:36:245164
[email protected]02965c22013-03-09 02:40:075165 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505166 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505167}
5168
5169void GLES2DecoderImpl::DoTexParameterfv(
5170 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]370eaf12013-05-18 09:19:495171 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:075172 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515173 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245174 return;
[email protected]3916c97e2010-02-25 03:20:505175 }
[email protected]cbb22e42011-05-12 23:36:245176
[email protected]02965c22013-03-09 02:40:075177 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505178 "glTexParameterfv", GetErrorState(), texture, pname,
5179 static_cast<GLint>(params[0]));
[email protected]3916c97e2010-02-25 03:20:505180}
5181
5182void GLES2DecoderImpl::DoTexParameteriv(
5183 GLenum target, GLenum pname, const GLint* params) {
[email protected]370eaf12013-05-18 09:19:495184 TextureRef* texture = GetTextureInfoForTarget(target);
[email protected]02965c22013-03-09 02:40:075185 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515186 LOCAL_SET_GL_ERROR(
5187 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245188 return;
[email protected]3916c97e2010-02-25 03:20:505189 }
[email protected]cbb22e42011-05-12 23:36:245190
[email protected]02965c22013-03-09 02:40:075191 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505192 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505193}
5194
[email protected]939e7362010-05-13 20:49:105195bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]e259eb412012-10-13 05:47:245196 if (!state_.current_program) {
[email protected]ad84a3a2012-06-08 21:42:435197 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515198 LOCAL_SET_GL_ERROR(
5199 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435200 return false;
[email protected]939e7362010-05-13 20:49:105201 }
[email protected]e259eb412012-10-13 05:47:245202 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515203 LOCAL_SET_GL_ERROR(
5204 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105205 return false;
5206 }
5207 return true;
5208}
5209
5210bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5211 GLint location, const char* function_name) {
5212 if (!CheckCurrentProgram(function_name)) {
5213 return false;
5214 }
5215 return location != -1;
5216}
5217
[email protected]476ccb72012-12-06 15:52:525218namespace {
5219
5220static const GLenum valid_int_vec1_types_list[] = {
5221 GL_INT,
5222 GL_BOOL,
5223 GL_SAMPLER_2D,
5224 GL_SAMPLER_2D_RECT_ARB,
5225 GL_SAMPLER_CUBE,
5226 GL_SAMPLER_EXTERNAL_OES,
5227};
5228
5229static const GLenum valid_int_vec2_types_list[] = {
5230 GL_INT_VEC2,
5231 GL_BOOL_VEC2,
5232};
5233
5234static const GLenum valid_int_vec3_types_list[] = {
5235 GL_INT_VEC3,
5236 GL_BOOL_VEC3,
5237};
5238
5239static const GLenum valid_int_vec4_types_list[] = {
5240 GL_INT_VEC4,
5241 GL_BOOL_VEC4,
5242};
5243
5244static const GLenum valid_float_vec1_types_list[] = {
5245 GL_FLOAT,
5246 GL_BOOL,
5247};
5248
5249static const GLenum valid_float_vec2_types_list[] = {
5250 GL_FLOAT_VEC2,
5251 GL_BOOL_VEC2,
5252};
5253
5254static const GLenum valid_float_vec3_types_list[] = {
5255 GL_FLOAT_VEC3,
5256 GL_BOOL_VEC3,
5257};
5258
5259static const GLenum valid_float_vec4_types_list[] = {
5260 GL_FLOAT_VEC4,
5261 GL_BOOL_VEC4,
5262};
5263
5264static const GLenum valid_float_mat2_types_list[] = {
5265 GL_FLOAT_MAT2,
5266};
5267
5268static const GLenum valid_float_mat3_types_list[] = {
5269 GL_FLOAT_MAT3,
5270};
5271
5272static const GLenum valid_float_mat4_types_list[] = {
5273 GL_FLOAT_MAT4,
5274};
5275
5276static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec1_base_info = {
5277 valid_int_vec1_types_list,
5278 arraysize(valid_int_vec1_types_list),
5279};
5280
5281static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec2_base_info = {
5282 valid_int_vec2_types_list,
5283 arraysize(valid_int_vec2_types_list),
5284};
5285
5286static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec3_base_info = {
5287 valid_int_vec3_types_list,
5288 arraysize(valid_int_vec3_types_list),
5289};
5290
5291static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec4_base_info = {
5292 valid_int_vec4_types_list,
5293 arraysize(valid_int_vec4_types_list),
5294};
5295
5296static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec1_base_info = {
5297 valid_float_vec1_types_list,
5298 arraysize(valid_float_vec1_types_list),
5299};
5300
5301static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec2_base_info = {
5302 valid_float_vec2_types_list,
5303 arraysize(valid_float_vec2_types_list),
5304};
5305
5306static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec3_base_info = {
5307 valid_float_vec3_types_list,
5308 arraysize(valid_float_vec3_types_list),
5309};
5310
5311static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec4_base_info = {
5312 valid_float_vec4_types_list,
5313 arraysize(valid_float_vec4_types_list),
5314};
5315
5316static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat2_base_info = {
5317 valid_float_mat2_types_list,
5318 arraysize(valid_float_mat2_types_list),
5319};
5320
5321static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat3_base_info = {
5322 valid_float_mat3_types_list,
5323 arraysize(valid_float_mat3_types_list),
5324};
5325
5326static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat4_base_info = {
5327 valid_float_mat4_types_list,
5328 arraysize(valid_float_mat4_types_list),
5329};
5330
5331} // anonymous namespace.
5332
[email protected]43c2f1f2011-03-25 18:35:365333bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:125334 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:525335 const GLES2DecoderImpl::BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:125336 GLint* real_location, GLenum* type, GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365337 DCHECK(type);
5338 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125339 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525340
[email protected]1b0a6752012-02-22 03:44:125341 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105342 return false;
5343 }
[email protected]43c2f1f2011-03-25 18:35:365344 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355345 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245346 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125347 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365348 if (!info) {
[email protected]ab09b612013-03-11 22:11:515349 LOCAL_SET_GL_ERROR(
5350 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105351 return false;
5352 }
[email protected]476ccb72012-12-06 15:52:525353 bool okay = false;
5354 for (size_t ii = 0; ii < base_info.num_valid_types; ++ii) {
5355 if (base_info.valid_types[ii] == info->type) {
5356 okay = true;
5357 break;
5358 }
5359 }
5360 if (!okay) {
[email protected]ab09b612013-03-11 22:11:515361 LOCAL_SET_GL_ERROR(
5362 GL_INVALID_OPERATION, function_name,
5363 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525364 return false;
5365 }
[email protected]43c2f1f2011-03-25 18:35:365366 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515367 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435368 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365369 return false;
5370 }
5371 *count = std::min(info->size - array_index, *count);
5372 if (*count <= 0) {
5373 return false;
5374 }
5375 *type = info->type;
[email protected]939e7362010-05-13 20:49:105376 return true;
5377}
5378
[email protected]1b0a6752012-02-22 03:44:125379void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5380 GLenum type = 0;
5381 GLsizei count = 1;
5382 GLint real_location = -1;
5383 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525384 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5385 &real_location, &type, &count)) {
[email protected]3916c97e2010-02-25 03:20:505386 return;
5387 }
[email protected]e259eb412012-10-13 05:47:245388 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025389 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515390 LOCAL_SET_GL_ERROR(
5391 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465392 return;
5393 }
[email protected]1b0a6752012-02-22 03:44:125394 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505395}
5396
5397void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125398 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365399 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125400 GLint real_location = -1;
5401 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525402 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5403 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365404 return;
5405 }
[email protected]74727112012-06-13 21:18:085406 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5407 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245408 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025409 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515410 LOCAL_SET_GL_ERROR(
5411 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465412 return;
5413 }
[email protected]43c2f1f2011-03-25 18:35:365414 }
[email protected]1b0a6752012-02-22 03:44:125415 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505416}
5417
[email protected]939e7362010-05-13 20:49:105418void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125419 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365420 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125421 GLint real_location = -1;
5422 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525423 fake_location, "glUniform1fv", valid_float_vec1_base_info,
5424 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105425 return;
5426 }
5427 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:555428 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:105429 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535430 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105431 }
[email protected]1b0a6752012-02-22 03:44:125432 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105433 } else {
[email protected]1b0a6752012-02-22 03:44:125434 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105435 }
5436}
5437
5438void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125439 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365440 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125441 GLint real_location = -1;
5442 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525443 fake_location, "glUniform2fv", valid_float_vec2_base_info,
5444 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105445 return;
5446 }
5447 if (type == GL_BOOL_VEC2) {
5448 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:555449 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105450 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535451 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105452 }
[email protected]1b0a6752012-02-22 03:44:125453 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105454 } else {
[email protected]1b0a6752012-02-22 03:44:125455 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105456 }
5457}
5458
5459void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125460 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365461 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125462 GLint real_location = -1;
5463 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525464 fake_location, "glUniform3fv", valid_float_vec3_base_info,
5465 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105466 return;
5467 }
5468 if (type == GL_BOOL_VEC3) {
5469 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:555470 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105471 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535472 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105473 }
[email protected]1b0a6752012-02-22 03:44:125474 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105475 } else {
[email protected]1b0a6752012-02-22 03:44:125476 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105477 }
5478}
5479
5480void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125481 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365482 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125483 GLint real_location = -1;
5484 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525485 fake_location, "glUniform4fv", valid_float_vec4_base_info,
5486 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105487 return;
5488 }
5489 if (type == GL_BOOL_VEC4) {
5490 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:555491 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105492 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535493 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105494 }
[email protected]1b0a6752012-02-22 03:44:125495 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105496 } else {
[email protected]1b0a6752012-02-22 03:44:125497 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105498 }
5499}
5500
[email protected]43c2f1f2011-03-25 18:35:365501void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125502 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365503 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125504 GLint real_location = -1;
5505 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525506 fake_location, "glUniform2iv", valid_int_vec2_base_info,
5507 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365508 return;
5509 }
[email protected]1b0a6752012-02-22 03:44:125510 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365511}
5512
5513void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125514 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365515 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125516 GLint real_location = -1;
5517 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525518 fake_location, "glUniform3iv", valid_int_vec3_base_info,
5519 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365520 return;
5521 }
[email protected]1b0a6752012-02-22 03:44:125522 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365523}
5524
5525void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125526 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365527 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125528 GLint real_location = -1;
5529 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525530 fake_location, "glUniform4iv", valid_int_vec4_base_info,
5531 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365532 return;
5533 }
[email protected]1b0a6752012-02-22 03:44:125534 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365535}
5536
5537void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:125538 GLint fake_location, GLsizei count, GLboolean transpose,
5539 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365540 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125541 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365542 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525543 fake_location, "glUniformMatrix2fv", valid_float_mat2_base_info,
5544 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365545 return;
5546 }
[email protected]1b0a6752012-02-22 03:44:125547 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365548}
5549
5550void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:125551 GLint fake_location, GLsizei count, GLboolean transpose,
5552 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365553 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125554 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365555 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525556 fake_location, "glUniformMatrix3fv", valid_float_mat3_base_info,
5557 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365558 return;
5559 }
[email protected]1b0a6752012-02-22 03:44:125560 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365561}
5562
5563void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:125564 GLint fake_location, GLsizei count, GLboolean transpose,
5565 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365566 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125567 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365568 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525569 fake_location, "glUniformMatrix4fv", valid_float_mat4_base_info,
5570 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365571 return;
5572 }
[email protected]1b0a6752012-02-22 03:44:125573 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365574}
5575
[email protected]df37b9932013-03-08 05:21:425576void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:035577 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:425578 Program* program = NULL;
5579 if (program_id) {
5580 program = GetProgramInfoNotShader(program_id, "glUseProgram");
5581 if (!program) {
[email protected]ae51d192010-04-27 00:48:035582 return;
5583 }
[email protected]df37b9932013-03-08 05:21:425584 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:505585 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:515586 LOCAL_SET_GL_ERROR(
5587 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:505588 return;
5589 }
[email protected]df37b9932013-03-08 05:21:425590 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:505591 }
[email protected]e259eb412012-10-13 05:47:245592 if (state_.current_program) {
5593 program_manager()->UnuseProgram(shader_manager(), state_.current_program);
[email protected]ca488e12010-12-13 20:06:145594 }
[email protected]df37b9932013-03-08 05:21:425595 state_.current_program = program;
5596 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:545597 glUseProgram(service_id);
[email protected]e259eb412012-10-13 05:47:245598 if (state_.current_program) {
5599 program_manager()->UseProgram(state_.current_program);
[email protected]ca488e12010-12-13 20:06:145600 }
[email protected]3916c97e2010-02-25 03:20:505601}
5602
[email protected]ab09b612013-03-11 22:11:515603void GLES2DecoderImpl::RenderWarning(
5604 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:325605 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015606}
5607
[email protected]ab09b612013-03-11 22:11:515608void GLES2DecoderImpl::PerformanceWarning(
5609 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:505610 logger_.LogMessage(filename, line,
5611 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015612}
5613
[email protected]df37b9932013-03-08 05:21:425614void GLES2DecoderImpl::ForceCompileShaderIfPending(Shader* shader) {
5615 if (shader->compilation_status() ==
[email protected]ed9f9cd2013-02-27 21:12:355616 Shader::PENDING_DEFERRED_COMPILE) {
[email protected]c447acd2012-07-23 23:48:415617 ShaderTranslator* translator = NULL;
5618 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:425619 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]c447acd2012-07-23 23:48:415620 vertex_translator_.get() : fragment_translator_.get();
5621 }
5622 // We know there will be no errors, because we only defer compilation on
5623 // shaders that were previously compiled successfully.
[email protected]df37b9932013-03-08 05:21:425624 program_manager()->ForceCompileShader(shader->deferred_compilation_source(),
5625 shader,
[email protected]c447acd2012-07-23 23:48:415626 translator,
5627 feature_info_);
5628 }
5629}
5630
[email protected]ef526492010-06-02 23:12:255631bool GLES2DecoderImpl::SetBlackTextureForNonRenderableTextures() {
[email protected]e259eb412012-10-13 05:47:245632 DCHECK(state_.current_program);
[email protected]ef526492010-06-02 23:12:255633 // Only check if there are some unrenderable textures.
5634 if (!texture_manager()->HaveUnrenderableTextures()) {
5635 return false;
5636 }
[email protected]5190e942013-05-17 03:53:425637 LOCAL_PERFORMANCE_WARNING("Some textures are unrenderable.");
[email protected]ef526492010-06-02 23:12:255638 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:355639 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245640 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505641 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355642 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245643 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505644 DCHECK(uniform_info);
5645 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5646 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025647 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245648 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:495649 TextureRef* texture =
[email protected]61eeb33f2011-07-26 15:30:315650 texture_unit.GetInfoForSamplerType(uniform_info->type);
[email protected]02965c22013-03-09 02:40:075651 if (!texture || !texture_manager()->CanRender(texture)) {
[email protected]ef526492010-06-02 23:12:255652 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:505653 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5654 glBindTexture(
[email protected]61eeb33f2011-07-26 15:30:315655 GetBindTargetForSamplerType(uniform_info->type),
[email protected]00f893d2010-08-24 18:55:495656 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:515657 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:015658 std::string("texture bound to texture unit ") +
5659 base::IntToString(texture_unit_index) +
5660 " is not renderable. It maybe non-power-of-2 and have "
5661 " incompatible texture filtering or is not "
5662 "'texture complete'");
[email protected]3916c97e2010-02-25 03:20:505663 }
5664 }
5665 // else: should this be an error?
5666 }
5667 }
[email protected]ef526492010-06-02 23:12:255668 return textures_set;
[email protected]3916c97e2010-02-25 03:20:505669}
5670
5671void GLES2DecoderImpl::RestoreStateForNonRenderableTextures() {
[email protected]e259eb412012-10-13 05:47:245672 DCHECK(state_.current_program);
[email protected]ed9f9cd2013-02-27 21:12:355673 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245674 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505675 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355676 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245677 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505678 DCHECK(uniform_info);
5679 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5680 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025681 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245682 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:495683 TextureRef* texture_ref = uniform_info->type == GL_SAMPLER_2D ?
[email protected]02965c22013-03-09 02:40:075684 texture_unit.bound_texture_2d :
5685 texture_unit.bound_texture_cube_map;
[email protected]370eaf12013-05-18 09:19:495686 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:505687 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:495688 // Get the texture_ref info that was previously bound here.
5689 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D ?
[email protected]3916c97e2010-02-25 03:20:505690 texture_unit.bound_texture_2d :
5691 texture_unit.bound_texture_cube_map;
5692 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:495693 texture_ref ? texture_ref->service_id() : 0);
[email protected]3916c97e2010-02-25 03:20:505694 }
5695 }
5696 }
5697 }
5698 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:245699 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:305700}
5701
[email protected]0d6bfdc2011-11-02 01:32:205702bool GLES2DecoderImpl::ClearUnclearedTextures() {
5703 // Only check if there are some uncleared textures.
5704 if (!texture_manager()->HaveUnsafeTextures()) {
5705 return true;
5706 }
5707
5708 // 1: Check all textures we are about to render with.
[email protected]e259eb412012-10-13 05:47:245709 if (state_.current_program) {
[email protected]ed9f9cd2013-02-27 21:12:355710 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245711 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:205712 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355713 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245714 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:205715 DCHECK(uniform_info);
5716 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5717 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025718 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245719 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:495720 TextureRef* texture_ref =
[email protected]0d6bfdc2011-11-02 01:32:205721 texture_unit.GetInfoForSamplerType(uniform_info->type);
[email protected]370eaf12013-05-18 09:19:495722 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
5723 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:205724 return false;
5725 }
5726 }
5727 }
5728 }
5729 }
5730 }
5731 return true;
5732}
5733
[email protected]c6aef902012-02-14 03:31:425734bool GLES2DecoderImpl::IsDrawValid(
[email protected]ad84a3a2012-06-08 21:42:435735 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
[email protected]689fa1c52010-06-09 18:35:035736 // NOTE: We specifically do not check current_program->IsValid() because
5737 // it could never be invalid since glUseProgram would have failed. While
5738 // glLinkProgram could later mark the program as invalid the previous
5739 // valid program will still function if it is still the current program.
[email protected]e259eb412012-10-13 05:47:245740 if (!state_.current_program) {
[email protected]3916c97e2010-02-25 03:20:505741 // The program does not exist.
5742 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:515743 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:505744 return false;
5745 }
[email protected]c6aef902012-02-14 03:31:425746
[email protected]17cfbe0e2013-03-07 01:26:085747 return state_.vertex_attrib_manager->ValidateBindings(
5748 function_name,
5749 this,
5750 feature_info_.get(),
5751 state_.current_program,
5752 max_vertex_accessed,
5753 primcount);
[email protected]b1122982010-05-17 23:04:245754}
5755
[email protected]c13e1da62011-09-09 21:48:305756bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:435757 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:305758 DCHECK(simulated);
5759 *simulated = false;
5760
[email protected]876f6fee2010-08-02 23:10:325761 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:305762 return true;
[email protected]876f6fee2010-08-02 23:10:325763
[email protected]ac77603c72013-03-08 13:52:065764 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:355765 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:245766 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:245767 bool attrib_0_used =
5768 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:065769 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:305770 return true;
[email protected]b1122982010-05-17 23:04:245771 }
5772
[email protected]b1122982010-05-17 23:04:245773 // Make a buffer with a single repeated vec4 value enough to
5774 // simulate the constant value that is supposed to be here.
5775 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:305776 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:475777 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:305778
5779 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:475780 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305781 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:515782 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305783 return false;
5784 }
5785
[email protected]ab09b612013-03-11 22:11:515786 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:015787 "Attribute 0 is disabled. This has signficant performance penalty");
5788
[email protected]ab09b612013-03-11 22:11:515789 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:305790 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
5791
[email protected]8f0b86c2f2012-04-10 05:48:285792 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
5793 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:495794 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305795 GLenum error = glGetError();
5796 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:515797 LOCAL_SET_GL_ERROR(
5798 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305799 return false;
5800 }
[email protected]fc753442011-02-04 19:49:495801 }
[email protected]af6380962012-11-29 23:24:135802
5803 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:285804 if (new_buffer ||
5805 (attrib_0_used &&
5806 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:135807 (value.v[0] != attrib_0_value_.v[0] ||
5808 value.v[1] != attrib_0_value_.v[1] ||
5809 value.v[2] != attrib_0_value_.v[2] ||
5810 value.v[3] != attrib_0_value_.v[3])))) {
5811 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:495812 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
5813 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:135814 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:245815 attrib_0_size_ = size_needed;
5816 }
5817
5818 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
5819
[email protected]ac77603c72013-03-08 13:52:065820 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:425821 glVertexAttribDivisorANGLE(0, 0);
5822
[email protected]c13e1da62011-09-09 21:48:305823 *simulated = true;
[email protected]b1122982010-05-17 23:04:245824 return true;
[email protected]b1122982010-05-17 23:04:245825}
5826
[email protected]ac77603c72013-03-08 13:52:065827void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib_index) {
5828 const VertexAttrib* attrib =
5829 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
5830 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
5831 Buffer* buffer = attrib->buffer();
[email protected]b10492f2013-03-08 05:24:075832 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
[email protected]b1122982010-05-17 23:04:245833 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:065834 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
5835 attrib->gl_stride(), ptr);
5836 if (attrib->divisor())
5837 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:245838 glBindBuffer(
5839 GL_ARRAY_BUFFER,
5840 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0);
[email protected]43410e92012-04-20 17:06:285841
[email protected]265f8992012-07-20 01:03:145842 // Never touch vertex attribute 0's state (in particular, never
5843 // disable it) when running on desktop GL because it will never be
5844 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:065845 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:145846 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:065847 if (attrib->enabled()) {
5848 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:145849 } else {
[email protected]ac77603c72013-03-08 13:52:065850 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:145851 }
[email protected]43410e92012-04-20 17:06:285852 }
[email protected]b1122982010-05-17 23:04:245853}
[email protected]07f54fcc2009-12-22 02:46:305854
[email protected]8fbedc02010-11-18 18:43:405855bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:435856 const char* function_name,
[email protected]c6aef902012-02-14 03:31:425857 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:405858 DCHECK(simulated);
5859 *simulated = false;
5860 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
5861 return true;
5862
[email protected]e259eb412012-10-13 05:47:245863 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:405864 return true;
5865 }
5866
[email protected]ab09b612013-03-11 22:11:515867 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:015868 "GL_FIXED attributes have a signficant performance penalty");
5869
[email protected]8fbedc02010-11-18 18:43:405870 // NOTE: we could be smart and try to check if a buffer is used
5871 // twice in 2 different attribs, find the overlapping parts and therefore
5872 // duplicate the minimum amount of data but this whole code path is not meant
5873 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
5874 // tests so we just add to the buffer attrib used.
5875
[email protected]c13e1da62011-09-09 21:48:305876 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:065877 const VertexAttribManager::VertexAttribList& enabled_attribs =
5878 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
5879 for (VertexAttribManager::VertexAttribList::const_iterator it =
5880 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
5881 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:355882 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:065883 state_.current_program->GetAttribInfoByLocation(attrib->index());
5884 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
5885 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:425886 GLuint num_vertices = max_accessed + 1;
5887 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:515888 LOCAL_SET_GL_ERROR(
5889 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425890 return false;
5891 }
[email protected]8fbedc02010-11-18 18:43:405892 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:065893 attrib->CanAccess(max_accessed) &&
5894 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:475895 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:065896 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:475897 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:515898 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435899 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405900 return false;
5901 }
5902 }
5903 }
5904
[email protected]3aad1a32012-09-07 20:54:475905 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
5906 uint32 size_needed = 0;
5907 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305908 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:515909 LOCAL_SET_GL_ERROR(
5910 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:405911 return false;
5912 }
5913
[email protected]ab09b612013-03-11 22:11:515914 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:405915
5916 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:305917 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:405918 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305919 GLenum error = glGetError();
5920 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:515921 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435922 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:305923 return false;
5924 }
[email protected]8fbedc02010-11-18 18:43:405925 }
5926
5927 // Copy the elements and convert to float
5928 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:065929 for (VertexAttribManager::VertexAttribList::const_iterator it =
5930 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
5931 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:355932 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:065933 state_.current_program->GetAttribInfoByLocation(attrib->index());
5934 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:425935 max_vertex_accessed);
5936 GLuint num_vertices = max_accessed + 1;
5937 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:515938 LOCAL_SET_GL_ERROR(
5939 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:425940 return false;
5941 }
[email protected]8fbedc02010-11-18 18:43:405942 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:065943 attrib->CanAccess(max_accessed) &&
5944 attrib->type() == GL_FIXED) {
5945 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:405946 int size = num_elements * num_vertices;
[email protected]40d90a22013-04-09 03:39:555947 scoped_ptr<float[]> data(new float[size]);
[email protected]8fbedc02010-11-18 18:43:405948 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:065949 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:405950 const int32* end = src + num_elements;
5951 float* dst = data.get();
5952 while (src != end) {
5953 *dst++ = static_cast<float>(*src++) / 65536.0f;
5954 }
5955 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
5956 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:065957 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:405958 reinterpret_cast<GLvoid*>(offset));
5959 offset += size;
5960 }
5961 }
5962 *simulated = true;
5963 return true;
5964}
5965
5966void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
5967 // There's no need to call glVertexAttribPointer because we shadow all the
5968 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:245969 glBindBuffer(
5970 GL_ARRAY_BUFFER,
5971 state_.bound_array_buffer ? state_.bound_array_buffer->service_id() : 0);
[email protected]8fbedc02010-11-18 18:43:405972}
5973
[email protected]ad84a3a2012-06-08 21:42:435974error::Error GLES2DecoderImpl::DoDrawArrays(
5975 const char* function_name,
5976 bool instanced,
5977 GLenum mode,
5978 GLint first,
5979 GLsizei count,
5980 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:085981 if (ShouldDeferDraws())
5982 return error::kDeferCommandUntilLater;
[email protected]38d139d2011-07-14 00:38:435983 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:515984 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:435985 return error::kNoError;
5986 }
5987 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:515988 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:435989 return error::kNoError;
5990 }
[email protected]c6aef902012-02-14 03:31:425991 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:515992 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:425993 return error::kNoError;
5994 }
[email protected]ad84a3a2012-06-08 21:42:435995 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:435996 return error::kNoError;
5997 }
5998 // We have to check this here because the prototype for glDrawArrays
5999 // is GLint not GLsizei.
6000 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516001 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436002 return error::kNoError;
6003 }
6004
[email protected]c6aef902012-02-14 03:31:426005 if (count == 0 || (instanced && primcount == 0)) {
[email protected]ab09b612013-03-11 22:11:516006 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436007 return error::kNoError;
6008 }
6009
6010 GLuint max_vertex_accessed = first + count - 1;
[email protected]ad84a3a2012-06-08 21:42:436011 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206012 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516013 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206014 return error::kNoError;
6015 }
[email protected]c13e1da62011-09-09 21:48:306016 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436017 if (!SimulateAttrib0(
6018 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306019 return error::kNoError;
6020 }
[email protected]38d139d2011-07-14 00:38:436021 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436022 if (SimulateFixedAttribs(
6023 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6024 primcount)) {
[email protected]38d139d2011-07-14 00:38:436025 bool textures_set = SetBlackTextureForNonRenderableTextures();
6026 ApplyDirtyState();
[email protected]c6aef902012-02-14 03:31:426027 if (!instanced) {
6028 glDrawArrays(mode, first, count);
6029 } else {
6030 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6031 }
[email protected]22e3f552012-03-13 01:54:196032 ProcessPendingQueries();
[email protected]38d139d2011-07-14 00:38:436033 if (textures_set) {
6034 RestoreStateForNonRenderableTextures();
6035 }
6036 if (simulated_fixed_attribs) {
6037 RestoreStateForSimulatedFixedAttribs();
6038 }
6039 }
6040 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286041 RestoreStateForAttrib(0);
[email protected]38d139d2011-07-14 00:38:436042 }
[email protected]38d139d2011-07-14 00:38:436043 }
6044 return error::kNoError;
6045}
6046
[email protected]c6aef902012-02-14 03:31:426047error::Error GLES2DecoderImpl::HandleDrawArrays(
[email protected]ed9f9cd2013-02-27 21:12:356048 uint32 immediate_data_size, const cmds::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:436049 return DoDrawArrays("glDrawArrays",
6050 false,
[email protected]c6aef902012-02-14 03:31:426051 static_cast<GLenum>(c.mode),
6052 static_cast<GLint>(c.first),
6053 static_cast<GLsizei>(c.count),
6054 0);
6055}
6056
6057error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356058 uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156059 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516060 LOCAL_SET_GL_ERROR(
6061 GL_INVALID_OPERATION,
6062 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426063 return error::kNoError;
6064 }
[email protected]ad84a3a2012-06-08 21:42:436065 return DoDrawArrays("glDrawArraysIntancedANGLE",
6066 true,
[email protected]c6aef902012-02-14 03:31:426067 static_cast<GLenum>(c.mode),
6068 static_cast<GLint>(c.first),
6069 static_cast<GLsizei>(c.count),
6070 static_cast<GLsizei>(c.primcount));
6071}
6072
[email protected]ad84a3a2012-06-08 21:42:436073error::Error GLES2DecoderImpl::DoDrawElements(
6074 const char* function_name,
6075 bool instanced,
6076 GLenum mode,
6077 GLsizei count,
6078 GLenum type,
6079 int32 offset,
6080 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:086081 if (ShouldDeferDraws())
6082 return error::kDeferCommandUntilLater;
[email protected]e259eb412012-10-13 05:47:246083 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516084 LOCAL_SET_GL_ERROR(
6085 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296086 return error::kNoError;
6087 }
6088
[email protected]8eee29c2010-04-29 03:38:296089 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516090 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296091 return error::kNoError;
6092 }
6093 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516094 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296095 return error::kNoError;
6096 }
[email protected]9438b012010-06-15 22:55:056097 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516098 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296099 return error::kNoError;
6100 }
[email protected]9438b012010-06-15 22:55:056101 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516102 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296103 return error::kNoError;
6104 }
[email protected]c6aef902012-02-14 03:31:426105 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516106 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426107 return error::kNoError;
6108 }
[email protected]8eee29c2010-04-29 03:38:296109
[email protected]ad84a3a2012-06-08 21:42:436110 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276111 return error::kNoError;
6112 }
6113
[email protected]c6aef902012-02-14 03:31:426114 if (count == 0 || (instanced && primcount == 0)) {
[email protected]6c788fb72010-08-26 02:16:316115 return error::kNoError;
6116 }
6117
[email protected]8eee29c2010-04-29 03:38:296118 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086119 Buffer* element_array_buffer =
6120 state_.vertex_attrib_manager->element_array_buffer();
6121
6122 if (!element_array_buffer->GetMaxValueForRange(
6123 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516124 LOCAL_SET_GL_ERROR(
6125 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296126 return error::kNoError;
6127 }
6128
[email protected]ad84a3a2012-06-08 21:42:436129 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206130 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516131 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206132 return error::kNoError;
6133 }
[email protected]c13e1da62011-09-09 21:48:306134 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436135 if (!SimulateAttrib0(
6136 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306137 return error::kNoError;
6138 }
[email protected]8fbedc02010-11-18 18:43:406139 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436140 if (SimulateFixedAttribs(
6141 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6142 primcount)) {
[email protected]8fbedc02010-11-18 18:43:406143 bool textures_set = SetBlackTextureForNonRenderableTextures();
[email protected]297ca1c2011-06-20 23:08:466144 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086145 // TODO(gman): Refactor to hide these details in BufferManager or
6146 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406147 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086148 bool used_client_side_array = false;
6149 if (element_array_buffer->IsClientSideArray()) {
6150 used_client_side_array = true;
6151 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6152 indices = element_array_buffer->GetRange(offset, 0);
6153 }
6154
[email protected]c6aef902012-02-14 03:31:426155 if (!instanced) {
6156 glDrawElements(mode, count, type, indices);
6157 } else {
6158 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6159 }
[email protected]17cfbe0e2013-03-07 01:26:086160
6161 if (used_client_side_array) {
6162 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6163 element_array_buffer->service_id());
6164 }
6165
[email protected]22e3f552012-03-13 01:54:196166 ProcessPendingQueries();
[email protected]8fbedc02010-11-18 18:43:406167 if (textures_set) {
6168 RestoreStateForNonRenderableTextures();
6169 }
6170 if (simulated_fixed_attribs) {
6171 RestoreStateForSimulatedFixedAttribs();
6172 }
[email protected]ba3176a2009-12-16 18:19:466173 }
[email protected]b1122982010-05-17 23:04:246174 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286175 RestoreStateForAttrib(0);
[email protected]b1122982010-05-17 23:04:246176 }
[email protected]96449d2c2009-11-25 00:01:326177 }
[email protected]f7a64ee2010-02-01 22:24:146178 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326179}
6180
[email protected]c6aef902012-02-14 03:31:426181error::Error GLES2DecoderImpl::HandleDrawElements(
[email protected]ed9f9cd2013-02-27 21:12:356182 uint32 immediate_data_size, const cmds::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:436183 return DoDrawElements("glDrawElements",
6184 false,
[email protected]c6aef902012-02-14 03:31:426185 static_cast<GLenum>(c.mode),
6186 static_cast<GLsizei>(c.count),
6187 static_cast<GLenum>(c.type),
6188 static_cast<int32>(c.index_offset),
6189 0);
6190}
6191
6192error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356193 uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156194 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516195 LOCAL_SET_GL_ERROR(
6196 GL_INVALID_OPERATION,
6197 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426198 return error::kNoError;
6199 }
[email protected]ad84a3a2012-06-08 21:42:436200 return DoDrawElements("glDrawElementsInstancedANGLE",
6201 true,
[email protected]c6aef902012-02-14 03:31:426202 static_cast<GLenum>(c.mode),
6203 static_cast<GLsizei>(c.count),
6204 static_cast<GLenum>(c.type),
6205 static_cast<int32>(c.index_offset),
6206 static_cast<GLsizei>(c.primcount));
6207}
6208
[email protected]269200b12010-11-18 22:53:066209GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236210 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6211 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076212 Buffer* buffer = GetBuffer(buffer_id);
6213 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036214 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516215 LOCAL_SET_GL_ERROR(
6216 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236217 } else {
[email protected]b10492f2013-03-08 05:24:076218 if (!buffer->GetMaxValueForRange(
6219 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036220 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516221 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066222 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436223 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236224 }
6225 }
6226 return max_vertex_accessed;
6227}
6228
[email protected]96449d2c2009-11-25 00:01:326229// Calls glShaderSource for the various versions of the ShaderSource command.
6230// Assumes that data / data_size points to a piece of memory that is in range
6231// of whatever context it came from (shared memory, immediate memory, bucket
6232// memory.)
[email protected]45bf5152010-02-12 00:11:316233error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036234 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576235 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426236 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6237 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316238 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326239 }
[email protected]45bf5152010-02-12 00:11:316240 // Note: We don't actually call glShaderSource here. We wait until
6241 // the call to glCompileShader.
[email protected]df37b9932013-03-08 05:21:426242 shader->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:146243 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326244}
6245
[email protected]f7a64ee2010-02-01 22:24:146246error::Error GLES2DecoderImpl::HandleShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356247 uint32 immediate_data_size, const cmds::ShaderSource& c) {
[email protected]96449d2c2009-11-25 00:01:326248 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316249 const char* data = GetSharedMemoryAs<const char*>(
[email protected]96449d2c2009-11-25 00:01:326250 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]ba3176a2009-12-16 18:19:466251 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146252 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326253 }
[email protected]ae51d192010-04-27 00:48:036254 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]96449d2c2009-11-25 00:01:326255}
6256
[email protected]f7a64ee2010-02-01 22:24:146257error::Error GLES2DecoderImpl::HandleShaderSourceImmediate(
[email protected]ed9f9cd2013-02-27 21:12:356258 uint32 immediate_data_size, const cmds::ShaderSourceImmediate& c) {
[email protected]96449d2c2009-11-25 00:01:326259 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316260 const char* data = GetImmediateDataAs<const char*>(
[email protected]07f54fcc2009-12-22 02:46:306261 c, data_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:466262 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146263 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326264 }
[email protected]ae51d192010-04-27 00:48:036265 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]45bf5152010-02-12 00:11:316266}
6267
[email protected]558847a2010-03-24 07:02:546268error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
[email protected]ed9f9cd2013-02-27 21:12:356269 uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:546270 Bucket* bucket = GetBucket(c.data_bucket_id);
6271 if (!bucket || bucket->size() == 0) {
6272 return error::kInvalidArguments;
6273 }
6274 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036275 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546276 bucket->size() - 1);
6277}
6278
[email protected]ae51d192010-04-27 00:48:036279void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386280 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426281 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6282 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316283 return;
6284 }
[email protected]f57bb282010-11-12 00:51:346285 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186286 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426287 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456288 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416289 }
[email protected]de17df392010-04-23 21:09:416290
[email protected]df37b9932013-03-08 05:21:426291 program_manager()->DoCompileShader(shader, translator, feature_info_);
[email protected]45bf5152010-02-12 00:11:316292};
6293
[email protected]ddd968b82010-03-02 00:44:296294void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426295 GLuint shader_id, GLenum pname, GLint* params) {
6296 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6297 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296298 return;
6299 }
[email protected]8f1ccdac2010-05-19 21:01:486300 switch (pname) {
6301 case GL_SHADER_SOURCE_LENGTH:
[email protected]df37b9932013-03-08 05:21:426302 *params = shader->source() ? shader->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:486303 return;
6304 case GL_COMPILE_STATUS:
[email protected]df37b9932013-03-08 05:21:426305 *params = compile_shader_always_succeeds_ ? true : shader->IsValid();
[email protected]e5186162010-06-14 18:54:416306 return;
[email protected]8f1ccdac2010-05-19 21:01:486307 case GL_INFO_LOG_LENGTH:
[email protected]df37b9932013-03-08 05:21:426308 *params = shader->log_info() ? shader->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:416309 return;
[email protected]d6a53e42011-10-05 00:09:366310 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]df37b9932013-03-08 05:21:426311 ForceCompileShaderIfPending(shader);
6312 *params = shader->translated_source() ?
6313 shader->translated_source()->size() + 1 : 0;
[email protected]d6a53e42011-10-05 00:09:366314 return;
[email protected]8f1ccdac2010-05-19 21:01:486315 default:
6316 break;
[email protected]ddd968b82010-03-02 00:44:296317 }
[email protected]df37b9932013-03-08 05:21:426318 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296319}
6320
[email protected]ae51d192010-04-27 00:48:036321error::Error GLES2DecoderImpl::HandleGetShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356322 uint32 immediate_data_size, const cmds::GetShaderSource& c) {
[email protected]df37b9932013-03-08 05:21:426323 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036324 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6325 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426326 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
6327 if (!shader || !shader->source()) {
[email protected]8eee29c2010-04-29 03:38:296328 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296329 return error::kNoError;
6330 }
[email protected]df37b9932013-03-08 05:21:426331 bucket->SetFromString(shader->source()->c_str());
[email protected]ae51d192010-04-27 00:48:036332 return error::kNoError;
6333}
6334
[email protected]d6a53e42011-10-05 00:09:366335error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6336 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:356337 const cmds::GetTranslatedShaderSourceANGLE& c) {
[email protected]df37b9932013-03-08 05:21:426338 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366339 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6340 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426341 Shader* shader = GetShaderInfoNotProgram(
6342 shader_id, "glTranslatedGetShaderSourceANGLE");
6343 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366344 bucket->SetSize(0);
6345 return error::kNoError;
6346 }
[email protected]df37b9932013-03-08 05:21:426347 ForceCompileShaderIfPending(shader);
[email protected]d6a53e42011-10-05 00:09:366348
[email protected]df37b9932013-03-08 05:21:426349 bucket->SetFromString(shader->translated_source() ?
6350 shader->translated_source()->c_str() : NULL);
[email protected]d6a53e42011-10-05 00:09:366351 return error::kNoError;
6352}
6353
[email protected]ae51d192010-04-27 00:48:036354error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356355 uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426356 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586357 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6358 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426359 Program* program = GetProgramInfoNotShader(
6360 program_id, "glGetProgramInfoLog");
6361 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466362 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036363 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316364 }
[email protected]df37b9932013-03-08 05:21:426365 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036366 return error::kNoError;
6367}
6368
6369error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356370 uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426371 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586372 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6373 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426374 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
6375 if (!shader || !shader->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466376 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036377 return error::kNoError;
6378 }
[email protected]df37b9932013-03-08 05:21:426379 bucket->SetFromString(shader->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036380 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326381}
6382
[email protected]d058bca2012-11-26 10:27:266383bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6384 return state_.GetEnabled(cap);
6385}
6386
[email protected]1958e0e2010-04-22 05:17:156387bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:216388 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106389 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156390}
6391
6392bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356393 const Framebuffer* framebuffer =
6394 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106395 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156396}
6397
6398bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366399 // IsProgram is true for programs as soon as they are created, until they are
6400 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:356401 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:106402 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156403}
6404
6405bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356406 const Renderbuffer* renderbuffer =
6407 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106408 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156409}
6410
6411bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366412 // IsShader is true for shaders as soon as they are created, until they
6413 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:356414 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:106415 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156416}
6417
6418bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:496419 const TextureRef* texture_ref = GetTexture(client_id);
6420 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:036421}
6422
6423void GLES2DecoderImpl::DoAttachShader(
6424 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426425 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586426 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:426427 if (!program) {
[email protected]ae51d192010-04-27 00:48:036428 return;
[email protected]1958e0e2010-04-22 05:17:156429 }
[email protected]df37b9932013-03-08 05:21:426430 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
6431 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036432 return;
6433 }
[email protected]df37b9932013-03-08 05:21:426434 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516435 LOCAL_SET_GL_ERROR(
6436 GL_INVALID_OPERATION,
6437 "glAttachShader",
6438 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:316439 return;
6440 }
[email protected]df37b9932013-03-08 05:21:426441 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036442}
6443
6444void GLES2DecoderImpl::DoDetachShader(
6445 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426446 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586447 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:426448 if (!program) {
[email protected]ae51d192010-04-27 00:48:036449 return;
6450 }
[email protected]df37b9932013-03-08 05:21:426451 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
6452 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036453 return;
6454 }
[email protected]df37b9932013-03-08 05:21:426455 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516456 LOCAL_SET_GL_ERROR(
6457 GL_INVALID_OPERATION,
6458 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:226459 return;
6460 }
[email protected]df37b9932013-03-08 05:21:426461 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036462}
6463
6464void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:426465 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586466 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:426467 if (!program) {
[email protected]ae51d192010-04-27 00:48:036468 return;
6469 }
[email protected]df37b9932013-03-08 05:21:426470 program->Validate();
[email protected]1958e0e2010-04-22 05:17:156471}
6472
[email protected]ac77603c72013-03-08 13:52:066473void GLES2DecoderImpl::GetVertexAttribHelper(
6474 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:246475 switch (pname) {
6476 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:066477 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:246478 if (buffer && !buffer->IsDeleted()) {
6479 GLuint client_id;
6480 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6481 *params = client_id;
6482 }
6483 break;
6484 }
6485 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:066486 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:246487 break;
6488 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:066489 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:246490 break;
6491 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:066492 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:246493 break;
6494 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:066495 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:246496 break;
6497 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:066498 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:246499 break;
[email protected]c6aef902012-02-14 03:31:426500 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:066501 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:426502 break;
[email protected]ac77603c72013-03-08 13:52:066503 default:
6504 NOTREACHED();
6505 break;
6506 }
6507}
6508
6509void GLES2DecoderImpl::DoGetVertexAttribfv(
6510 GLuint index, GLenum pname, GLfloat* params) {
6511 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6512 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516513 LOCAL_SET_GL_ERROR(
6514 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066515 return;
6516 }
6517 switch (pname) {
6518 case GL_CURRENT_VERTEX_ATTRIB: {
6519 const Vec4& value = state_.attrib_values[index];
6520 params[0] = value.v[0];
6521 params[1] = value.v[1];
6522 params[2] = value.v[2];
6523 params[3] = value.v[3];
6524 break;
6525 }
6526 default: {
6527 GLint value = 0;
6528 GetVertexAttribHelper(attrib, pname, &value);
6529 *params = static_cast<GLfloat>(value);
6530 break;
6531 }
6532 }
6533}
6534
6535void GLES2DecoderImpl::DoGetVertexAttribiv(
6536 GLuint index, GLenum pname, GLint* params) {
6537 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6538 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516539 LOCAL_SET_GL_ERROR(
6540 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066541 return;
6542 }
6543 switch (pname) {
[email protected]af6380962012-11-29 23:24:136544 case GL_CURRENT_VERTEX_ATTRIB: {
6545 const Vec4& value = state_.attrib_values[index];
6546 params[0] = static_cast<GLint>(value.v[0]);
6547 params[1] = static_cast<GLint>(value.v[1]);
6548 params[2] = static_cast<GLint>(value.v[2]);
6549 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:246550 break;
[email protected]af6380962012-11-29 23:24:136551 }
[email protected]b1122982010-05-17 23:04:246552 default:
[email protected]ac77603c72013-03-08 13:52:066553 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:246554 break;
6555 }
6556}
6557
[email protected]af6380962012-11-29 23:24:136558bool GLES2DecoderImpl::SetVertexAttribValue(
6559 const char* function_name, GLuint index, const GLfloat* value) {
6560 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:516561 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:136562 return false;
[email protected]b1122982010-05-17 23:04:246563 }
[email protected]af6380962012-11-29 23:24:136564 Vec4& v = state_.attrib_values[index];
6565 v.v[0] = value[0];
6566 v.v[1] = value[1];
6567 v.v[2] = value[2];
6568 v.v[3] = value[3];
6569 return true;
6570}
6571
6572void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
6573 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
6574 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
6575 glVertexAttrib1f(index, v0);
6576 }
[email protected]b1122982010-05-17 23:04:246577}
6578
6579void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:136580 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
6581 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
6582 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:246583 }
[email protected]b1122982010-05-17 23:04:246584}
6585
6586void GLES2DecoderImpl::DoVertexAttrib3f(
6587 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:136588 GLfloat v[4] = { v0, v1, v2, 1.0f, };
6589 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
6590 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:246591 }
[email protected]b1122982010-05-17 23:04:246592}
6593
6594void GLES2DecoderImpl::DoVertexAttrib4f(
6595 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:136596 GLfloat v[4] = { v0, v1, v2, v3, };
6597 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
6598 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:246599 }
[email protected]b1122982010-05-17 23:04:246600}
6601
6602void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136603 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
6604 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
6605 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:246606 }
[email protected]b1122982010-05-17 23:04:246607}
6608
6609void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136610 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
6611 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
6612 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:246613 }
[email protected]b1122982010-05-17 23:04:246614}
6615
6616void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136617 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
6618 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
6619 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:246620 }
[email protected]b1122982010-05-17 23:04:246621}
6622
6623void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136624 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
6625 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:246626 }
[email protected]b1122982010-05-17 23:04:246627}
6628
[email protected]f7a64ee2010-02-01 22:24:146629error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]ed9f9cd2013-02-27 21:12:356630 uint32 immediate_data_size, const cmds::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:466631
[email protected]e259eb412012-10-13 05:47:246632 if (!state_.bound_array_buffer || state_.bound_array_buffer->IsDeleted()) {
6633 if (state_.vertex_attrib_manager == default_vertex_attrib_manager_) {
[email protected]ab09b612013-03-11 22:11:516634 LOCAL_SET_GL_ERROR(
6635 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:466636 return error::kNoError;
6637 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:516638 LOCAL_SET_GL_ERROR(
6639 GL_INVALID_VALUE,
6640 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:466641 return error::kNoError;
6642 }
[email protected]96449d2c2009-11-25 00:01:326643 }
[email protected]8eee29c2010-04-29 03:38:296644
6645 GLuint indx = c.indx;
6646 GLint size = c.size;
6647 GLenum type = c.type;
6648 GLboolean normalized = c.normalized;
6649 GLsizei stride = c.stride;
6650 GLsizei offset = c.offset;
6651 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:056652 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516653 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:296654 return error::kNoError;
6655 }
[email protected]9438b012010-06-15 22:55:056656 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:516657 LOCAL_SET_GL_ERROR(
6658 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:296659 return error::kNoError;
6660 }
6661 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516662 LOCAL_SET_GL_ERROR(
6663 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:296664 return error::kNoError;
6665 }
6666 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:516667 LOCAL_SET_GL_ERROR(
6668 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:296669 return error::kNoError;
6670 }
6671 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:516672 LOCAL_SET_GL_ERROR(
6673 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:296674 return error::kNoError;
6675 }
6676 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516677 LOCAL_SET_GL_ERROR(
6678 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296679 return error::kNoError;
6680 }
6681 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:316682 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]8eee29c2010-04-29 03:38:296683 if (offset % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:516684 LOCAL_SET_GL_ERROR(
6685 GL_INVALID_OPERATION,
6686 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:316687 return error::kNoError;
6688 }
6689 if (stride % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:516690 LOCAL_SET_GL_ERROR(
6691 GL_INVALID_OPERATION,
6692 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:296693 return error::kNoError;
6694 }
[email protected]e259eb412012-10-13 05:47:246695 state_.vertex_attrib_manager->SetAttribInfo(
[email protected]8fbedc02010-11-18 18:43:406696 indx,
[email protected]e259eb412012-10-13 05:47:246697 state_.bound_array_buffer,
[email protected]8eee29c2010-04-29 03:38:296698 size,
6699 type,
[email protected]b1122982010-05-17 23:04:246700 normalized,
6701 stride,
6702 stride != 0 ? stride : component_size * size,
[email protected]8eee29c2010-04-29 03:38:296703 offset);
[email protected]8fbedc02010-11-18 18:43:406704 if (type != GL_FIXED) {
6705 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
6706 }
[email protected]f7a64ee2010-02-01 22:24:146707 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326708}
6709
[email protected]43410e92012-04-20 17:06:286710void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
6711 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:246712 state_.viewport_x = x;
6713 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:026714 state_.viewport_width = std::min(width, viewport_max_width_);
6715 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:286716 glViewport(x, y, width, height);
6717}
6718
[email protected]c6aef902012-02-14 03:31:426719error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356720 uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156721 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516722 LOCAL_SET_GL_ERROR(
6723 GL_INVALID_OPERATION,
6724 "glVertexAttribDivisorANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426725 }
6726 GLuint index = c.index;
6727 GLuint divisor = c.divisor;
6728 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516729 LOCAL_SET_GL_ERROR(
6730 GL_INVALID_VALUE,
6731 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:426732 return error::kNoError;
6733 }
6734
[email protected]e259eb412012-10-13 05:47:246735 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:426736 index,
6737 divisor);
6738 glVertexAttribDivisorANGLE(index, divisor);
6739 return error::kNoError;
6740}
6741
[email protected]f7a64ee2010-02-01 22:24:146742error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]ed9f9cd2013-02-27 21:12:356743 uint32 immediate_data_size, const cmds::ReadPixels& c) {
[email protected]09e17272012-11-30 10:30:446744 if (ShouldDeferReads())
6745 return error::kDeferCommandUntilLater;
[email protected]612d2f82009-12-08 20:49:316746 GLint x = c.x;
6747 GLint y = c.y;
6748 GLsizei width = c.width;
6749 GLsizei height = c.height;
6750 GLenum format = c.format;
6751 GLenum type = c.type;
[email protected]57f223832010-03-19 01:57:566752 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:516753 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:566754 return error::kNoError;
6755 }
[email protected]ed9f9cd2013-02-27 21:12:356756 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:186757 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:346758 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246759 width, height, format, type, state_.pack_alignment, &pixels_size,
6760 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:186761 return error::kOutOfBounds;
6762 }
[email protected]612d2f82009-12-08 20:49:316763 void* pixels = GetSharedMemoryAs<void*>(
6764 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:106765 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:146766 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:466767 }
[email protected]de43f082013-04-02 01:16:106768 Result* result = NULL;
6769 if (c.result_shm_id != 0) {
6770 result = GetSharedMemoryAs<Result*>(
6771 c.result_shm_id, c.result_shm_offset, sizeof(*result));
6772 if (!result) {
6773 return error::kOutOfBounds;
6774 }
6775 }
[email protected]a51788e2010-02-24 21:54:256776
[email protected]9438b012010-06-15 22:55:056777 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:516778 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:296779 return error::kNoError;
6780 }
[email protected]9438b012010-06-15 22:55:056781 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516782 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:126783 return error::kNoError;
6784 }
[email protected]57f223832010-03-19 01:57:566785 if (width == 0 || height == 0) {
6786 return error::kNoError;
6787 }
6788
[email protected]57f223832010-03-19 01:57:566789 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:306790 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:566791
[email protected]3aad1a32012-09-07 20:54:476792 int32 max_x;
6793 int32 max_y;
6794 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:516795 LOCAL_SET_GL_ERROR(
6796 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:146797 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:316798 }
[email protected]57f223832010-03-19 01:57:566799
[email protected]0d6bfdc2011-11-02 01:32:206800 if (!CheckBoundFramebuffersValid("glReadPixels")) {
6801 return error::kNoError;
6802 }
6803
[email protected]ab09b612013-03-11 22:11:516804 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixel");
[email protected]a0b78dc2011-11-11 10:43:106805
6806 ScopedResolvedFrameBufferBinder binder(this, false, true);
6807
[email protected]d37231fa2010-04-09 21:16:026808 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:566809 // The user requested an out of range area. Get the results 1 line
6810 // at a time.
6811 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346812 uint32 unpadded_row_size;
6813 uint32 padded_row_size;
6814 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246815 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346816 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:516817 LOCAL_SET_GL_ERROR(
6818 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566819 return error::kNoError;
6820 }
6821
6822 GLint dest_x_offset = std::max(-x, 0);
6823 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:346824 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246825 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
6826 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:516827 LOCAL_SET_GL_ERROR(
6828 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:566829 return error::kNoError;
6830 }
6831
6832 // Copy each row into the larger dest rect.
6833 int8* dst = static_cast<int8*>(pixels);
6834 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:026835 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:566836 GLint read_width = read_end_x - read_x;
6837 for (GLint yy = 0; yy < height; ++yy) {
6838 GLint ry = y + yy;
6839
6840 // Clear the row.
6841 memset(dst, 0, unpadded_row_size);
6842
6843 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:026844 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:566845 glReadPixels(
6846 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
6847 }
6848 dst += padded_row_size;
6849 }
6850 } else {
6851 glReadPixels(x, y, width, height, format, type, pixels);
6852 }
[email protected]ab09b612013-03-11 22:11:516853 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:256854 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:106855 if (result != NULL) {
6856 *result = true;
6857 }
[email protected]4848b9f82011-03-10 18:37:566858
6859 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
6860 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
[email protected]84eb4252012-06-29 22:56:446861 if ((channels_exist & 0x0008) == 0 &&
[email protected]62e155e2012-10-23 22:43:156862 workarounds().clear_alpha_in_readpixels) {
[email protected]4848b9f82011-03-10 18:37:566863 // Set the alpha to 255 because some drivers are buggy in this regard.
6864 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:346865
6866 uint32 unpadded_row_size;
6867 uint32 padded_row_size;
6868 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:246869 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:346870 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:516871 LOCAL_SET_GL_ERROR(
6872 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]4848b9f82011-03-10 18:37:566873 return error::kNoError;
6874 }
6875 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time
6876 // of this implementation.
6877 if (type != GL_UNSIGNED_BYTE) {
[email protected]ab09b612013-03-11 22:11:516878 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436879 GL_INVALID_OPERATION, "glReadPixels",
6880 "unsupported readPixel format");
[email protected]4848b9f82011-03-10 18:37:566881 return error::kNoError;
6882 }
6883 switch (format) {
6884 case GL_RGBA:
[email protected]297ca1c2011-06-20 23:08:466885 case GL_BGRA_EXT:
[email protected]4848b9f82011-03-10 18:37:566886 case GL_ALPHA: {
6887 int offset = (format == GL_ALPHA) ? 0 : 3;
6888 int step = (format == GL_ALPHA) ? 1 : 4;
6889 uint8* dst = static_cast<uint8*>(pixels) + offset;
6890 for (GLint yy = 0; yy < height; ++yy) {
6891 uint8* end = dst + unpadded_row_size;
6892 for (uint8* d = dst; d < end; d += step) {
6893 *d = 255;
6894 }
6895 dst += padded_row_size;
6896 }
6897 break;
6898 }
6899 default:
6900 break;
6901 }
6902 }
[email protected]a51788e2010-02-24 21:54:256903 }
[email protected]4848b9f82011-03-10 18:37:566904
[email protected]f7a64ee2010-02-01 22:24:146905 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326906}
6907
[email protected]f7a64ee2010-02-01 22:24:146908error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]ed9f9cd2013-02-27 21:12:356909 uint32 immediate_data_size, const cmds::PixelStorei& c) {
[email protected]b9849abf2009-11-25 19:13:196910 GLenum pname = c.pname;
6911 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:056912 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:516913 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:126914 return error::kNoError;
6915 }
[email protected]222471d2011-11-30 18:06:396916 switch (pname) {
6917 case GL_PACK_ALIGNMENT:
6918 case GL_UNPACK_ALIGNMENT:
6919 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:516920 LOCAL_SET_GL_ERROR(
6921 GL_INVALID_VALUE, "glPixelStore", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:396922 return error::kNoError;
6923 }
[email protected]164d6d52012-05-05 00:55:036924 break;
[email protected]0a1e9ad2012-05-04 21:13:036925 case GL_UNPACK_FLIP_Y_CHROMIUM:
6926 unpack_flip_y_ = (param != 0);
6927 return error::kNoError;
6928 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
6929 unpack_premultiply_alpha_ = (param != 0);
6930 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:176931 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
6932 unpack_unpremultiply_alpha_ = (param != 0);
6933 return error::kNoError;
[email protected]222471d2011-11-30 18:06:396934 default:
6935 break;
[email protected]b9849abf2009-11-25 19:13:196936 }
6937 glPixelStorei(pname, param);
6938 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:436939 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246940 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436941 break;
6942 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:426943 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:436944 break;
6945 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:246946 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:436947 break;
6948 default:
6949 // Validation should have prevented us from getting here.
6950 NOTREACHED();
6951 break;
[email protected]b9849abf2009-11-25 19:13:196952 }
[email protected]f7a64ee2010-02-01 22:24:146953 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196954}
6955
[email protected]1c75a3702011-11-11 14:15:286956error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:356957 uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:386958 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]6f5fac9d12012-06-26 21:02:456959 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) {
[email protected]ab09b612013-03-11 22:11:516960 LOCAL_SET_GL_ERROR(
6961 GL_INVALID_OPERATION,
6962 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:286963 return error::kNoError;
6964 }
[email protected]7794d512012-04-17 20:36:496965 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:286966 return error::kNoError;
[email protected]7794d512012-04-17 20:36:496967 } else {
6968 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:286969 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:496970 }
[email protected]1c75a3702011-11-11 14:15:286971}
6972
[email protected]558847a2010-03-24 07:02:546973error::Error GLES2DecoderImpl::GetAttribLocationHelper(
6974 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
6975 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:576976 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:516977 LOCAL_SET_GL_ERROR(
6978 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:576979 return error::kNoError;
6980 }
[email protected]df37b9932013-03-08 05:21:426981 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586982 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:426983 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:146984 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:196985 }
[email protected]df37b9932013-03-08 05:21:426986 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:516987 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436988 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:256989 return error::kNoError;
6990 }
[email protected]b9849abf2009-11-25 19:13:196991 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:546992 location_shm_id, location_shm_offset, sizeof(GLint));
6993 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:146994 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:196995 }
[email protected]558847a2010-03-24 07:02:546996 // Require the client to init this incase the context is lost and we are no
6997 // longer executing commands.
6998 if (*location != -1) {
6999 return error::kGenericError;
7000 }
[email protected]df37b9932013-03-08 05:21:427001 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147002 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197003}
7004
[email protected]558847a2010-03-24 07:02:547005error::Error GLES2DecoderImpl::HandleGetAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:357006 uint32 immediate_data_size, const cmds::GetAttribLocation& c) {
[email protected]558847a2010-03-24 07:02:547007 uint32 name_size = c.data_size;
7008 const char* name = GetSharedMemoryAs<const char*>(
7009 c.name_shm_id, c.name_shm_offset, name_size);
7010 if (!name) {
7011 return error::kOutOfBounds;
7012 }
7013 String name_str(name, name_size);
7014 return GetAttribLocationHelper(
7015 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7016}
7017
[email protected]f7a64ee2010-02-01 22:24:147018error::Error GLES2DecoderImpl::HandleGetAttribLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357019 uint32 immediate_data_size, const cmds::GetAttribLocationImmediate& c) {
[email protected]558847a2010-03-24 07:02:547020 uint32 name_size = c.data_size;
7021 const char* name = GetImmediateDataAs<const char*>(
7022 c, name_size, immediate_data_size);
7023 if (!name) {
7024 return error::kOutOfBounds;
7025 }
7026 String name_str(name, name_size);
7027 return GetAttribLocationHelper(
7028 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7029}
7030
7031error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357032 uint32 immediate_data_size, const cmds::GetAttribLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547033 Bucket* bucket = GetBucket(c.name_bucket_id);
7034 if (!bucket) {
7035 return error::kInvalidArguments;
7036 }
7037 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187038 if (!bucket->GetAsString(&name_str)) {
7039 return error::kInvalidArguments;
7040 }
[email protected]558847a2010-03-24 07:02:547041 return GetAttribLocationHelper(
7042 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7043}
7044
7045error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7046 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7047 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577048 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517049 LOCAL_SET_GL_ERROR(
7050 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577051 return error::kNoError;
7052 }
[email protected]df37b9932013-03-08 05:21:427053 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587054 client_id, "glUniformLocation");
[email protected]df37b9932013-03-08 05:21:427055 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147056 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197057 }
[email protected]df37b9932013-03-08 05:21:427058 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517059 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437060 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257061 return error::kNoError;
7062 }
[email protected]b9849abf2009-11-25 19:13:197063 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547064 location_shm_id, location_shm_offset, sizeof(GLint));
7065 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147066 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197067 }
[email protected]558847a2010-03-24 07:02:547068 // Require the client to init this incase the context is lost an we are no
7069 // longer executing commands.
7070 if (*location != -1) {
7071 return error::kGenericError;
7072 }
[email protected]df37b9932013-03-08 05:21:427073 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147074 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197075}
7076
[email protected]f7a64ee2010-02-01 22:24:147077error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]ed9f9cd2013-02-27 21:12:357078 uint32 immediate_data_size, const cmds::GetUniformLocation& c) {
[email protected]b9849abf2009-11-25 19:13:197079 uint32 name_size = c.data_size;
7080 const char* name = GetSharedMemoryAs<const char*>(
7081 c.name_shm_id, c.name_shm_offset, name_size);
[email protected]558847a2010-03-24 07:02:547082 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147083 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197084 }
7085 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547086 return GetUniformLocationHelper(
7087 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197088}
7089
[email protected]f7a64ee2010-02-01 22:24:147090error::Error GLES2DecoderImpl::HandleGetUniformLocationImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357091 uint32 immediate_data_size, const cmds::GetUniformLocationImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197092 uint32 name_size = c.data_size;
[email protected]07f54fcc2009-12-22 02:46:307093 const char* name = GetImmediateDataAs<const char*>(
7094 c, name_size, immediate_data_size);
[email protected]558847a2010-03-24 07:02:547095 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147096 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197097 }
7098 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547099 return GetUniformLocationHelper(
7100 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7101}
7102
7103error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357104 uint32 immediate_data_size, const cmds::GetUniformLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547105 Bucket* bucket = GetBucket(c.name_bucket_id);
7106 if (!bucket) {
7107 return error::kInvalidArguments;
7108 }
7109 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187110 if (!bucket->GetAsString(&name_str)) {
7111 return error::kInvalidArguments;
7112 }
[email protected]558847a2010-03-24 07:02:547113 return GetUniformLocationHelper(
7114 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197115}
7116
[email protected]ddd968b82010-03-02 00:44:297117error::Error GLES2DecoderImpl::HandleGetString(
[email protected]ed9f9cd2013-02-27 21:12:357118 uint32 immediate_data_size, const cmds::GetString& c) {
[email protected]ddd968b82010-03-02 00:44:297119 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057120 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517121 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297122 return error::kNoError;
7123 }
[email protected]1958e0e2010-04-22 05:17:157124 const char* gl_str = reinterpret_cast<const char*>(glGetString(name));
7125 const char* str = NULL;
[email protected]f0d74742011-10-03 16:31:047126 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157127 switch (name) {
7128 case GL_VERSION:
7129 str = "OpenGL ES 2.0 Chromium";
7130 break;
7131 case GL_SHADING_LANGUAGE_VERSION:
7132 str = "OpenGL ES GLSL ES 1.0 Chromium";
7133 break;
[email protected]32939602012-05-09 06:25:167134 case GL_RENDERER:
7135 str = "Chromium";
7136 break;
7137 case GL_VENDOR:
7138 str = "Chromium";
7139 break;
[email protected]1958e0e2010-04-22 05:17:157140 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047141 {
7142 // For WebGL contexts, strip out the OES derivatives extension if it has
7143 // not been enabled.
7144 if (force_webgl_glsl_validation_ &&
7145 !derivatives_explicitly_enabled_) {
7146 extensions = feature_info_->extensions();
7147 size_t offset = extensions.find(kOESDerivativeExtension);
7148 if (std::string::npos != offset) {
7149 extensions.replace(offset,
7150 offset + arraysize(kOESDerivativeExtension),
7151 std::string());
7152 }
[email protected]f0d74742011-10-03 16:31:047153 } else {
[email protected]6f5fac9d12012-06-26 21:02:457154 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047155 }
[email protected]6f5fac9d12012-06-26 21:02:457156 std::string surface_extensions = surface_->GetExtensions();
7157 if (!surface_extensions.empty())
7158 extensions += " " + surface_extensions;
7159 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047160 }
[email protected]1958e0e2010-04-22 05:17:157161 break;
7162 default:
7163 str = gl_str;
7164 break;
7165 }
[email protected]ddd968b82010-03-02 00:44:297166 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157167 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297168 return error::kNoError;
7169}
7170
[email protected]0c86dbf2010-03-05 08:14:117171void GLES2DecoderImpl::DoBufferData(
[email protected]b9363b22010-06-09 22:06:157172 GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) {
[email protected]9438b012010-06-15 22:55:057173 if (!validators_->buffer_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517174 LOCAL_SET_GL_ERROR_INVALID_ENUM("glBufferData", target, "target");
[email protected]8eee29c2010-04-29 03:38:297175 return;
7176 }
[email protected]9438b012010-06-15 22:55:057177 if (!validators_->buffer_usage.IsValid(usage)) {
[email protected]ab09b612013-03-11 22:11:517178 LOCAL_SET_GL_ERROR_INVALID_ENUM("glBufferData", usage, "usage");
[email protected]0c86dbf2010-03-05 08:14:117179 return;
[email protected]3b6ec202010-03-05 05:16:237180 }
7181 if (size < 0) {
[email protected]ab09b612013-03-11 22:11:517182 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferData", "size < 0");
[email protected]037896bd2010-04-21 19:07:287183 return;
[email protected]3b6ec202010-03-05 05:16:237184 }
[email protected]17cfbe0e2013-03-07 01:26:087185 Buffer* buffer = GetBufferInfoForTarget(target);
7186 if (!buffer) {
[email protected]ab09b612013-03-11 22:11:517187 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:287188 return;
[email protected]3b6ec202010-03-05 05:16:237189 }
[email protected]7989c9e2013-01-23 06:39:267190
7191 if (!EnsureGPUMemoryAvailable(size)) {
[email protected]ab09b612013-03-11 22:11:517192 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glBufferData", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267193 return;
7194 }
7195
[email protected]d3eba342013-04-18 21:11:507196 buffer_manager()->DoBufferData(GetErrorState(), buffer, size, usage, data);
[email protected]0c86dbf2010-03-05 08:14:117197}
7198
7199error::Error GLES2DecoderImpl::HandleBufferData(
[email protected]ed9f9cd2013-02-27 21:12:357200 uint32 immediate_data_size, const cmds::BufferData& c) {
[email protected]0c86dbf2010-03-05 08:14:117201 GLenum target = static_cast<GLenum>(c.target);
7202 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7203 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7204 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7205 GLenum usage = static_cast<GLenum>(c.usage);
7206 const void* data = NULL;
7207 if (data_shm_id != 0 || data_shm_offset != 0) {
7208 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7209 if (!data) {
7210 return error::kOutOfBounds;
7211 }
7212 }
7213 DoBufferData(target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147214 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197215}
7216
[email protected]f7a64ee2010-02-01 22:24:147217error::Error GLES2DecoderImpl::HandleBufferDataImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357218 uint32 immediate_data_size, const cmds::BufferDataImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197219 GLenum target = static_cast<GLenum>(c.target);
7220 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
[email protected]07f54fcc2009-12-22 02:46:307221 const void* data = GetImmediateDataAs<const void*>(
7222 c, size, immediate_data_size);
7223 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147224 return error::kOutOfBounds;
[email protected]07f54fcc2009-12-22 02:46:307225 }
[email protected]b9849abf2009-11-25 19:13:197226 GLenum usage = static_cast<GLenum>(c.usage);
[email protected]0c86dbf2010-03-05 08:14:117227 DoBufferData(target, size, data, usage);
7228 return error::kNoError;
7229}
7230
7231void GLES2DecoderImpl::DoBufferSubData(
7232 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]17cfbe0e2013-03-07 01:26:087233 Buffer* buffer = GetBufferInfoForTarget(target);
7234 if (!buffer) {
[email protected]ab09b612013-03-11 22:11:517235 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glBufferSubData", "unknown buffer");
[email protected]037896bd2010-04-21 19:07:287236 return;
[email protected]a93bb842010-02-16 23:03:477237 }
[email protected]17cfbe0e2013-03-07 01:26:087238
[email protected]d3eba342013-04-18 21:11:507239 buffer_manager()->DoBufferSubData(GetErrorState(), buffer, offset, size,
7240 data);
[email protected]b9849abf2009-11-25 19:13:197241}
7242
[email protected]0d6bfdc2011-11-02 01:32:207243bool GLES2DecoderImpl::ClearLevel(
7244 unsigned service_id,
7245 unsigned bind_target,
7246 unsigned target,
7247 int level,
7248 unsigned format,
7249 unsigned type,
7250 int width,
[email protected]4502e6492011-12-14 19:39:157251 int height,
7252 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007253 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7254 if (IsAngle() && (channels & GLES2Util::kDepth) != 0) {
7255 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7256 // on depth formats.
7257 GLuint fb = 0;
7258 glGenFramebuffersEXT(1, &fb);
7259 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7260
7261 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7262 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7263 GL_DEPTH_ATTACHMENT;
7264
7265 glFramebufferTexture2DEXT(
7266 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7267 // ANGLE promises a depth only attachment ok.
7268 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7269 GL_FRAMEBUFFER_COMPLETE) {
7270 return false;
7271 }
7272 glClearStencil(0);
7273 glStencilMask(-1);
7274 glClearDepth(1.0f);
7275 glDepthMask(true);
7276 glDisable(GL_SCISSOR_TEST);
7277 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7278
7279 RestoreClearState();
7280
7281 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:357282 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:007283 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7284 GLuint fb_service_id =
7285 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7286 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7287 return true;
7288 }
7289
[email protected]45d15a62012-04-18 14:33:177290 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7291
7292 uint32 size;
7293 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:347294 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247295 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:177296 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:207297 return false;
7298 }
[email protected]45d15a62012-04-18 14:33:177299
[email protected]a5d3dad2012-05-26 04:34:447300 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7301
[email protected]45d15a62012-04-18 14:33:177302 int tile_height;
7303
7304 if (size > kMaxZeroSize) {
7305 if (kMaxZeroSize < padded_row_size) {
7306 // That'd be an awfully large texture.
7307 return false;
7308 }
7309 // We should never have a large total size with a zero row size.
7310 DCHECK_GT(padded_row_size, 0U);
7311 tile_height = kMaxZeroSize / padded_row_size;
7312 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247313 width, tile_height, format, type, state_.unpack_alignment, &size,
7314 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:177315 return false;
7316 }
[email protected]4502e6492011-12-14 19:39:157317 } else {
[email protected]45d15a62012-04-18 14:33:177318 tile_height = height;
7319 }
7320
7321 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:557322 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:177323 memset(zero.get(), 0, size);
7324 glBindTexture(bind_target, service_id);
7325
7326 GLint y = 0;
7327 while (y < height) {
7328 GLint h = y + tile_height > height ? height - y : tile_height;
7329 if (is_texture_immutable || h != height) {
7330 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7331 } else {
[email protected]8f1d2aa2013-05-10 23:45:387332 glTexImage2D(
[email protected]45d15a62012-04-18 14:33:177333 target, level, format, width, h, 0, format, type, zero.get());
7334 }
7335 y += tile_height;
[email protected]4502e6492011-12-14 19:39:157336 }
[email protected]370eaf12013-05-18 09:19:497337 TextureRef* texture = GetTextureInfoForTarget(bind_target);
[email protected]02965c22013-03-09 02:40:077338 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:207339 return true;
7340}
7341
[email protected]ad84a3a2012-06-08 21:42:437342namespace {
7343
7344const int kS3TCBlockWidth = 4;
7345const int kS3TCBlockHeight = 4;
7346const int kS3TCDXT1BlockSize = 8;
7347const int kS3TCDXT3AndDXT5BlockSize = 16;
[email protected]2d3765b2012-10-03 00:31:077348const int kETC1BlockWidth = 4;
7349const int kETC1BlockHeight = 4;
7350const int kETC1BlockSize = 8;
[email protected]ad84a3a2012-06-08 21:42:437351
7352bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:517353 return (size == 1) ||
7354 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:437355}
7356
7357} // anonymous namespace.
7358
7359bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7360 const char* function_name,
7361 GLsizei width, GLsizei height, GLenum format, size_t size) {
7362 unsigned int bytes_required = 0;
7363
7364 switch (format) {
7365 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7366 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: {
7367 int num_blocks_across =
7368 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7369 int num_blocks_down =
7370 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7371 int num_blocks = num_blocks_across * num_blocks_down;
7372 bytes_required = num_blocks * kS3TCDXT1BlockSize;
7373 break;
7374 }
7375 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7376 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7377 int num_blocks_across =
7378 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7379 int num_blocks_down =
7380 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7381 int num_blocks = num_blocks_across * num_blocks_down;
7382 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
7383 break;
7384 }
[email protected]2d3765b2012-10-03 00:31:077385 case GL_ETC1_RGB8_OES: {
7386 int num_blocks_across =
7387 (width + kETC1BlockWidth - 1) / kETC1BlockWidth;
7388 int num_blocks_down =
7389 (height + kETC1BlockHeight - 1) / kETC1BlockHeight;
7390 int num_blocks = num_blocks_across * num_blocks_down;
7391 bytes_required = num_blocks * kETC1BlockSize;
7392 break;
7393 }
[email protected]ad84a3a2012-06-08 21:42:437394 default:
[email protected]ab09b612013-03-11 22:11:517395 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:437396 return false;
7397 }
7398
7399 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:517400 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437401 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
7402 return false;
7403 }
7404
7405 return true;
7406}
7407
7408bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
7409 const char* function_name,
7410 GLint level, GLsizei width, GLsizei height, GLenum format) {
7411 switch (format) {
7412 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7413 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7414 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7415 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7416 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:517417 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437418 GL_INVALID_OPERATION, function_name,
7419 "width or height invalid for level");
7420 return false;
7421 }
7422 return true;
7423 }
[email protected]2d3765b2012-10-03 00:31:077424 case GL_ETC1_RGB8_OES:
7425 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:517426 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077427 GL_INVALID_OPERATION, function_name,
7428 "width or height invalid for level");
7429 return false;
7430 }
7431 return true;
[email protected]ad84a3a2012-06-08 21:42:437432 default:
7433 return false;
7434 }
7435}
7436
7437bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
7438 const char* function_name,
7439 GLenum target, GLint level, GLint xoffset, GLint yoffset,
7440 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:357441 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:437442 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:517443 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437444 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
7445 return false;
7446 }
7447
7448 switch (format) {
7449 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7450 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7451 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7452 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7453 const int kBlockWidth = 4;
7454 const int kBlockHeight = 4;
7455 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:517456 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437457 GL_INVALID_OPERATION, function_name,
7458 "xoffset or yoffset not multiple of 4");
7459 return false;
7460 }
7461 GLsizei tex_width = 0;
7462 GLsizei tex_height = 0;
7463 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
7464 width - xoffset > tex_width ||
7465 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:517466 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437467 GL_INVALID_OPERATION, function_name, "dimensions out of range");
7468 return false;
7469 }
7470 return ValidateCompressedTexDimensions(
7471 function_name, level, width, height, format);
7472 }
[email protected]2d3765b2012-10-03 00:31:077473 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:517474 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077475 GL_INVALID_OPERATION, function_name,
7476 "TexsubImage2d not supported for ECT1_RGB8_OES textures");
7477 return false;
7478 }
[email protected]ad84a3a2012-06-08 21:42:437479 default:
7480 return false;
7481 }
7482}
7483
[email protected]a93bb842010-02-16 23:03:477484error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
7485 GLenum target,
7486 GLint level,
7487 GLenum internal_format,
7488 GLsizei width,
7489 GLsizei height,
7490 GLint border,
7491 GLsizei image_size,
7492 const void* data) {
[email protected]a93bb842010-02-16 23:03:477493 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:057494 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517495 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7496 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297497 return error::kNoError;
7498 }
[email protected]9438b012010-06-15 22:55:057499 if (!validators_->compressed_texture_format.IsValid(
7500 internal_format)) {
[email protected]ab09b612013-03-11 22:11:517501 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:537502 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:477503 return error::kNoError;
7504 }
[email protected]80eb6b52012-01-19 00:14:417505 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477506 border != 0) {
[email protected]ab09b612013-03-11 22:11:517507 LOCAL_SET_GL_ERROR(
7508 GL_INVALID_VALUE,
7509 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:477510 return error::kNoError;
7511 }
[email protected]370eaf12013-05-18 09:19:497512 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7513 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517514 LOCAL_SET_GL_ERROR(
7515 GL_INVALID_VALUE,
7516 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:477517 return error::kNoError;
7518 }
[email protected]370eaf12013-05-18 09:19:497519 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:077520 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517521 LOCAL_SET_GL_ERROR(
7522 GL_INVALID_OPERATION,
7523 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:437524 return error::kNoError;
7525 }
7526
7527 if (!ValidateCompressedTexDimensions(
7528 "glCompressedTexImage2D", level, width, height, internal_format) ||
7529 !ValidateCompressedTexFuncData(
7530 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:177531 return error::kNoError;
7532 }
[email protected]968351b2011-12-20 08:26:517533
[email protected]7989c9e2013-01-23 06:39:267534 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:517535 LOCAL_SET_GL_ERROR(
7536 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267537 return error::kNoError;
7538 }
7539
[email protected]02965c22013-03-09 02:40:077540 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427541 clear_state_dirty_ = true;
[email protected]968351b2011-12-20 08:26:517542 }
7543
[email protected]40d90a22013-04-09 03:39:557544 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:477545 if (!data) {
7546 zero.reset(new int8[image_size]);
7547 memset(zero.get(), 0, image_size);
7548 data = zero.get();
7549 }
[email protected]ab09b612013-03-11 22:11:517550 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:477551 glCompressedTexImage2D(
7552 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:517553 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:437554 if (error == GL_NO_ERROR) {
7555 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497556 texture_ref, target, level, internal_format,
7557 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:437558 }
[email protected]a93bb842010-02-16 23:03:477559 return error::kNoError;
7560}
7561
[email protected]f7a64ee2010-02-01 22:24:147562error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357563 uint32 immediate_data_size, const cmds::CompressedTexImage2D& c) {
[email protected]b9849abf2009-11-25 19:13:197564 GLenum target = static_cast<GLenum>(c.target);
7565 GLint level = static_cast<GLint>(c.level);
7566 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7567 GLsizei width = static_cast<GLsizei>(c.width);
7568 GLsizei height = static_cast<GLsizei>(c.height);
7569 GLint border = static_cast<GLint>(c.border);
7570 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
7571 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7572 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7573 const void* data = NULL;
7574 if (data_shm_id != 0 || data_shm_offset != 0) {
7575 data = GetSharedMemoryAs<const void*>(
7576 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:467577 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147578 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197579 }
7580 }
[email protected]a93bb842010-02-16 23:03:477581 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197582 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:197583}
7584
[email protected]f7a64ee2010-02-01 22:24:147585error::Error GLES2DecoderImpl::HandleCompressedTexImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357586 uint32 immediate_data_size, const cmds::CompressedTexImage2DImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197587 GLenum target = static_cast<GLenum>(c.target);
7588 GLint level = static_cast<GLint>(c.level);
7589 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7590 GLsizei width = static_cast<GLsizei>(c.width);
7591 GLsizei height = static_cast<GLsizei>(c.height);
7592 GLint border = static_cast<GLint>(c.border);
7593 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
[email protected]07f54fcc2009-12-22 02:46:307594 const void* data = GetImmediateDataAs<const void*>(
7595 c, image_size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467596 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147597 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467598 }
[email protected]a93bb842010-02-16 23:03:477599 return DoCompressedTexImage2D(
7600 target, level, internal_format, width, height, border, image_size, data);
7601}
7602
[email protected]b6140d02010-05-17 14:47:167603error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
[email protected]ed9f9cd2013-02-27 21:12:357604 uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167605 GLenum target = static_cast<GLenum>(c.target);
7606 GLint level = static_cast<GLint>(c.level);
7607 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7608 GLsizei width = static_cast<GLsizei>(c.width);
7609 GLsizei height = static_cast<GLsizei>(c.height);
7610 GLint border = static_cast<GLint>(c.border);
7611 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287612 if (!bucket) {
7613 return error::kInvalidArguments;
7614 }
7615 uint32 data_size = bucket->size();
7616 GLsizei imageSize = data_size;
7617 const void* data = bucket->GetData(0, data_size);
7618 if (!data) {
7619 return error::kInvalidArguments;
7620 }
[email protected]b6140d02010-05-17 14:47:167621 return DoCompressedTexImage2D(
7622 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:287623 imageSize, data);
[email protected]b6140d02010-05-17 14:47:167624}
7625
7626error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
7627 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:357628 const cmds::CompressedTexSubImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167629 GLenum target = static_cast<GLenum>(c.target);
7630 GLint level = static_cast<GLint>(c.level);
7631 GLint xoffset = static_cast<GLint>(c.xoffset);
7632 GLint yoffset = static_cast<GLint>(c.yoffset);
7633 GLsizei width = static_cast<GLsizei>(c.width);
7634 GLsizei height = static_cast<GLsizei>(c.height);
7635 GLenum format = static_cast<GLenum>(c.format);
7636 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287637 if (!bucket) {
7638 return error::kInvalidArguments;
7639 }
[email protected]b6140d02010-05-17 14:47:167640 uint32 data_size = bucket->size();
7641 GLsizei imageSize = data_size;
7642 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:287643 if (!data) {
7644 return error::kInvalidArguments;
7645 }
[email protected]9438b012010-06-15 22:55:057646 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517647 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:537648 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:167649 return error::kNoError;
7650 }
[email protected]9438b012010-06-15 22:55:057651 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517652 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7653 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:057654 return error::kNoError;
7655 }
[email protected]b6140d02010-05-17 14:47:167656 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:517657 LOCAL_SET_GL_ERROR(
7658 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:167659 return error::kNoError;
7660 }
7661 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:517662 LOCAL_SET_GL_ERROR(
7663 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:167664 return error::kNoError;
7665 }
7666 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:517667 LOCAL_SET_GL_ERROR(
7668 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:167669 return error::kNoError;
7670 }
[email protected]cadde4a2010-07-31 17:10:437671 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:167672 target, level, xoffset, yoffset, width, height, format, imageSize, data);
7673 return error::kNoError;
7674}
7675
[email protected]81375742012-06-08 00:04:007676bool GLES2DecoderImpl::ValidateTextureParameters(
7677 const char* function_name,
7678 GLenum target, GLenum format, GLenum type, GLint level) {
7679 if (!feature_info_->GetTextureFormatValidator(format).IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517680 LOCAL_SET_GL_ERROR(
7681 GL_INVALID_OPERATION, function_name,
7682 (std::string("invalid type ") +
7683 GLES2Util::GetStringEnum(type) + " for format " +
7684 GLES2Util::GetStringEnum(format)).c_str());
[email protected]81375742012-06-08 00:04:007685 return false;
7686 }
7687
7688 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7689 if ((channels & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && level) {
[email protected]ab09b612013-03-11 22:11:517690 LOCAL_SET_GL_ERROR(
7691 GL_INVALID_OPERATION, function_name,
7692 (std::string("invalid type ") +
7693 GLES2Util::GetStringEnum(type) + " for format " +
7694 GLES2Util::GetStringEnum(format)).c_str());
[email protected]81375742012-06-08 00:04:007695 return false;
7696 }
7697 return true;
7698}
7699
[email protected]f598f422012-12-07 08:30:037700bool GLES2DecoderImpl::ValidateTexImage2D(
7701 const char* function_name,
7702 GLenum target,
7703 GLint level,
7704 GLenum internal_format,
7705 GLsizei width,
7706 GLsizei height,
7707 GLint border,
7708 GLenum format,
7709 GLenum type,
7710 const void* pixels,
7711 uint32 pixels_size) {
[email protected]9438b012010-06-15 22:55:057712 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517713 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:037714 return false;
[email protected]8eee29c2010-04-29 03:38:297715 }
[email protected]9438b012010-06-15 22:55:057716 if (!validators_->texture_format.IsValid(internal_format)) {
[email protected]ab09b612013-03-11 22:11:517717 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7718 function_name, internal_format, "internal_format");
[email protected]f598f422012-12-07 08:30:037719 return false;
[email protected]8eee29c2010-04-29 03:38:297720 }
[email protected]9438b012010-06-15 22:55:057721 if (!validators_->texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517722 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]f598f422012-12-07 08:30:037723 return false;
[email protected]8eee29c2010-04-29 03:38:297724 }
[email protected]9438b012010-06-15 22:55:057725 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517726 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]f598f422012-12-07 08:30:037727 return false;
[email protected]b9849abf2009-11-25 19:13:197728 }
[email protected]7b92c412010-07-20 17:48:257729 if (format != internal_format) {
[email protected]ab09b612013-03-11 22:11:517730 LOCAL_SET_GL_ERROR(
7731 GL_INVALID_OPERATION, function_name, "format != internalFormat");
[email protected]f598f422012-12-07 08:30:037732 return false;
[email protected]7b92c412010-07-20 17:48:257733 }
[email protected]f598f422012-12-07 08:30:037734 if (!ValidateTextureParameters(function_name, target, format, type, level)) {
7735 return false;
[email protected]81375742012-06-08 00:04:007736 }
[email protected]80eb6b52012-01-19 00:14:417737 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477738 border != 0) {
[email protected]ab09b612013-03-11 22:11:517739 LOCAL_SET_GL_ERROR(
7740 GL_INVALID_VALUE, function_name, "dimensions out of range");
[email protected]f598f422012-12-07 08:30:037741 return false;
[email protected]a93bb842010-02-16 23:03:477742 }
[email protected]81375742012-06-08 00:04:007743 if ((GLES2Util::GetChannelsForFormat(format) &
7744 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0 && pixels) {
[email protected]ab09b612013-03-11 22:11:517745 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:007746 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:037747 function_name, "can not supply data for depth or stencil textures");
7748 return false;
[email protected]81375742012-06-08 00:04:007749 }
[email protected]370eaf12013-05-18 09:19:497750 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7751 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517752 LOCAL_SET_GL_ERROR(
7753 GL_INVALID_OPERATION, function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:037754 return false;
[email protected]a93bb842010-02-16 23:03:477755 }
[email protected]370eaf12013-05-18 09:19:497756 if (texture_ref->texture()->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517757 LOCAL_SET_GL_ERROR(
7758 GL_INVALID_OPERATION, function_name, "texture is immutable");
[email protected]f598f422012-12-07 08:30:037759 return false;
[email protected]97dc7cbe2011-12-06 17:26:177760 }
[email protected]f598f422012-12-07 08:30:037761 return true;
7762}
[email protected]97dc7cbe2011-12-06 17:26:177763
[email protected]f598f422012-12-07 08:30:037764void GLES2DecoderImpl::DoTexImage2D(
7765 GLenum target,
7766 GLint level,
7767 GLenum internal_format,
7768 GLsizei width,
7769 GLsizei height,
7770 GLint border,
7771 GLenum format,
7772 GLenum type,
7773 const void* pixels,
7774 uint32 pixels_size) {
7775 if (!ValidateTexImage2D("glTexImage2D", target, level, internal_format,
7776 width, height, border, format, type, pixels, pixels_size)) {
7777 return;
7778 }
[email protected]7989c9e2013-01-23 06:39:267779
7780 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:517781 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267782 return;
7783 }
7784
[email protected]370eaf12013-05-18 09:19:497785 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7786 Texture* texture = texture_ref->texture();
[email protected]0226c112011-07-22 03:25:077787 GLsizei tex_width = 0;
7788 GLsizei tex_height = 0;
7789 GLenum tex_type = 0;
7790 GLenum tex_format = 0;
7791 bool level_is_same =
[email protected]02965c22013-03-09 02:40:077792 texture->GetLevelSize(target, level, &tex_width, &tex_height) &&
7793 texture->GetLevelType(target, level, &tex_type, &tex_format) &&
[email protected]0226c112011-07-22 03:25:077794 width == tex_width && height == tex_height &&
7795 type == tex_type && format == tex_format;
7796
7797 if (level_is_same && !pixels) {
[email protected]02965c22013-03-09 02:40:077798 // Just set the level texture but mark the texture as uncleared.
[email protected]1bed6222011-12-21 11:21:397799 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497800 texture_ref,
[email protected]1bed6222011-12-21 11:21:397801 target, level, internal_format, width, height, 1, border, format, type,
7802 false);
[email protected]ea72ed222011-08-17 18:58:437803 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:037804 return;
[email protected]0226c112011-07-22 03:25:077805 }
7806
[email protected]02965c22013-03-09 02:40:077807 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:427808 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:467809 }
7810
[email protected]1bed6222011-12-21 11:21:397811 if (!teximage2d_faster_than_texsubimage2d_ && level_is_same && pixels) {
[email protected]0226c112011-07-22 03:25:077812 glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels);
[email protected]370eaf12013-05-18 09:19:497813 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]0226c112011-07-22 03:25:077814 tex_image_2d_failed_ = false;
[email protected]f598f422012-12-07 08:30:037815 return;
[email protected]7488d962010-07-16 02:41:587816 }
[email protected]876f6fee2010-08-02 23:10:327817
[email protected]ab09b612013-03-11 22:11:517818 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexImage2D");
[email protected]8f1d2aa2013-05-10 23:45:387819 glTexImage2D(
[email protected]473c01ccb2011-06-07 01:33:307820 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477821 pixels);
[email protected]ab09b612013-03-11 22:11:517822 GLenum error = LOCAL_PEEK_GL_ERROR("glTexImage2D");
[email protected]cadde4a2010-07-31 17:10:437823 if (error == GL_NO_ERROR) {
[email protected]0d6bfdc2011-11-02 01:32:207824 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497825 texture_ref,
[email protected]0d6bfdc2011-11-02 01:32:207826 target, level, internal_format, width, height, 1, border, format, type,
7827 pixels != NULL);
[email protected]b493ee622011-04-13 23:52:007828 tex_image_2d_failed_ = false;
[email protected]cadde4a2010-07-31 17:10:437829 }
[email protected]f598f422012-12-07 08:30:037830 return;
[email protected]b9849abf2009-11-25 19:13:197831}
7832
[email protected]f7a64ee2010-02-01 22:24:147833error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357834 uint32 immediate_data_size, const cmds::TexImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:387835 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
[email protected]b493ee622011-04-13 23:52:007836 tex_image_2d_failed_ = true;
[email protected]b9849abf2009-11-25 19:13:197837 GLenum target = static_cast<GLenum>(c.target);
7838 GLint level = static_cast<GLint>(c.level);
7839 GLint internal_format = static_cast<GLint>(c.internalformat);
7840 GLsizei width = static_cast<GLsizei>(c.width);
7841 GLsizei height = static_cast<GLsizei>(c.height);
7842 GLint border = static_cast<GLint>(c.border);
7843 GLenum format = static_cast<GLenum>(c.format);
7844 GLenum type = static_cast<GLenum>(c.type);
7845 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
7846 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:187847 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347848 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247849 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:347850 NULL)) {
[email protected]a76b0052010-03-05 00:33:187851 return error::kOutOfBounds;
7852 }
[email protected]b9849abf2009-11-25 19:13:197853 const void* pixels = NULL;
7854 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
7855 pixels = GetSharedMemoryAs<const void*>(
7856 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:467857 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147858 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197859 }
7860 }
[email protected]f598f422012-12-07 08:30:037861
7862 DoTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197863 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477864 pixels, pixels_size);
[email protected]f598f422012-12-07 08:30:037865 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197866}
7867
[email protected]f7a64ee2010-02-01 22:24:147868error::Error GLES2DecoderImpl::HandleTexImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:357869 uint32 immediate_data_size, const cmds::TexImage2DImmediate& c) {
[email protected]b9849abf2009-11-25 19:13:197870 GLenum target = static_cast<GLenum>(c.target);
7871 GLint level = static_cast<GLint>(c.level);
[email protected]ba3176a2009-12-16 18:19:467872 GLint internal_format = static_cast<GLint>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:197873 GLsizei width = static_cast<GLsizei>(c.width);
7874 GLsizei height = static_cast<GLsizei>(c.height);
7875 GLint border = static_cast<GLint>(c.border);
7876 GLenum format = static_cast<GLenum>(c.format);
7877 GLenum type = static_cast<GLenum>(c.type);
[email protected]a76b0052010-03-05 00:33:187878 uint32 size;
[email protected]3458a64a2012-04-10 17:39:347879 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247880 width, height, format, type, state_.unpack_alignment, &size,
7881 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187882 return error::kOutOfBounds;
7883 }
[email protected]07f54fcc2009-12-22 02:46:307884 const void* pixels = GetImmediateDataAs<const void*>(
7885 c, size, immediate_data_size);
[email protected]ba3176a2009-12-16 18:19:467886 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147887 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467888 }
[email protected]a93bb842010-02-16 23:03:477889 DoTexImage2D(
[email protected]ba3176a2009-12-16 18:19:467890 target, level, internal_format, width, height, border, format, type,
[email protected]a93bb842010-02-16 23:03:477891 pixels, size);
[email protected]f7a64ee2010-02-01 22:24:147892 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327893}
7894
[email protected]cadde4a2010-07-31 17:10:437895void GLES2DecoderImpl::DoCompressedTexSubImage2D(
7896 GLenum target,
7897 GLint level,
7898 GLint xoffset,
7899 GLint yoffset,
7900 GLsizei width,
7901 GLsizei height,
7902 GLenum format,
7903 GLsizei image_size,
7904 const void * data) {
[email protected]370eaf12013-05-18 09:19:497905 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7906 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517907 LOCAL_SET_GL_ERROR(
7908 GL_INVALID_OPERATION,
7909 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437910 return;
7911 }
[email protected]370eaf12013-05-18 09:19:497912 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:437913 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:527914 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:077915 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:517916 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:527917 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437918 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:527919 return;
7920 }
7921 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:517922 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:527923 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437924 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:527925 return;
7926 }
[email protected]02965c22013-03-09 02:40:077927 if (!texture->ValidForTexture(
[email protected]df6cf1ad2011-01-29 01:20:527928 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:517929 LOCAL_SET_GL_ERROR(
7930 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437931 return;
7932 }
[email protected]ad84a3a2012-06-08 21:42:437933
7934 if (!ValidateCompressedTexFuncData(
7935 "glCompressedTexSubImage2D", width, height, format, image_size) ||
7936 !ValidateCompressedTexSubDimensions(
7937 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:077938 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:437939 return;
7940 }
7941
7942
[email protected]0d6bfdc2011-11-02 01:32:207943 // Note: There is no need to deal with texture cleared tracking here
7944 // because the validation above means you can only get here if the level
7945 // is already a matching compressed format and in that case
7946 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:437947 glCompressedTexSubImage2D(
7948 target, level, xoffset, yoffset, width, height, format, image_size, data);
7949}
7950
[email protected]6e288612010-12-21 20:45:037951static void Clip(
7952 GLint start, GLint range, GLint sourceRange,
7953 GLint* out_start, GLint* out_range) {
7954 DCHECK(out_start);
7955 DCHECK(out_range);
7956 if (start < 0) {
7957 range += start;
7958 start = 0;
7959 }
7960 GLint end = start + range;
7961 if (end > sourceRange) {
7962 range -= end - sourceRange;
7963 }
7964 *out_start = start;
7965 *out_range = range;
7966}
7967
[email protected]cadde4a2010-07-31 17:10:437968void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:447969 GLenum target,
7970 GLint level,
7971 GLenum internal_format,
7972 GLint x,
7973 GLint y,
7974 GLsizei width,
7975 GLsizei height,
7976 GLint border) {
[email protected]09e17272012-11-30 10:30:447977 DCHECK(!ShouldDeferReads());
[email protected]370eaf12013-05-18 09:19:497978 TextureRef* texture_ref = GetTextureInfoForTarget(target);
7979 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517980 LOCAL_SET_GL_ERROR(
7981 GL_INVALID_OPERATION,
7982 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437983 return;
7984 }
[email protected]370eaf12013-05-18 09:19:497985 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:077986 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517987 LOCAL_SET_GL_ERROR(
7988 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:177989 }
[email protected]80eb6b52012-01-19 00:14:417990 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:187991 border != 0) {
[email protected]ab09b612013-03-11 22:11:517992 LOCAL_SET_GL_ERROR(
7993 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:187994 return;
7995 }
[email protected]81375742012-06-08 00:04:007996 if (!ValidateTextureParameters(
7997 "glCopyTexImage2D", target, internal_format, GL_UNSIGNED_BYTE, level)) {
7998 return;
7999 }
[email protected]f5719fb2010-08-04 18:27:188000
[email protected]9edc6b22010-12-23 02:00:268001 // Check we have compatible formats.
8002 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8003 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8004 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8005
8006 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518007 LOCAL_SET_GL_ERROR(
8008 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268009 return;
8010 }
8011
[email protected]81375742012-06-08 00:04:008012 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518013 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008014 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268015 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8016 return;
8017 }
8018
8019 uint32 estimated_size = 0;
8020 if (!GLES2Util::ComputeImageDataSizes(
8021 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8022 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518023 LOCAL_SET_GL_ERROR(
8024 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268025 return;
8026 }
8027
8028 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518029 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008030 return;
8031 }
8032
[email protected]a0b78dc2011-11-11 10:43:108033 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8034 return;
8035 }
8036
[email protected]ab09b612013-03-11 22:11:518037 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278038 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038039 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268040
[email protected]02965c22013-03-09 02:40:078041 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:428042 clear_state_dirty_ = true;
[email protected]297ca1c2011-06-20 23:08:468043 }
8044
[email protected]9edc6b22010-12-23 02:00:268045 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038046 GLint copyX = 0;
8047 GLint copyY = 0;
8048 GLint copyWidth = 0;
8049 GLint copyHeight = 0;
8050 Clip(x, width, size.width(), &copyX, &copyWidth);
8051 Clip(y, height, size.height(), &copyY, &copyHeight);
8052
8053 if (copyX != x ||
8054 copyY != y ||
8055 copyWidth != width ||
8056 copyHeight != height) {
8057 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208058 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078059 texture->service_id(), texture->target(),
[email protected]4502e6492011-12-14 19:39:158060 target, level, internal_format, GL_UNSIGNED_BYTE, width, height,
[email protected]02965c22013-03-09 02:40:078061 texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518062 LOCAL_SET_GL_ERROR(
8063 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038064 return;
8065 }
[email protected]6e288612010-12-21 20:45:038066 if (copyHeight > 0 && copyWidth > 0) {
8067 GLint dx = copyX - x;
8068 GLint dy = copyY - y;
8069 GLint destX = dx;
8070 GLint destY = dy;
8071 glCopyTexSubImage2D(target, level,
8072 destX, destY, copyX, copyY,
8073 copyWidth, copyHeight);
8074 }
8075 } else {
8076 glCopyTexImage2D(target, level, internal_format,
8077 copyX, copyY, copyWidth, copyHeight, border);
8078 }
[email protected]ab09b612013-03-11 22:11:518079 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438080 if (error == GL_NO_ERROR) {
8081 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498082 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208083 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438084 }
8085}
8086
8087void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448088 GLenum target,
8089 GLint level,
8090 GLint xoffset,
8091 GLint yoffset,
8092 GLint x,
8093 GLint y,
8094 GLsizei width,
8095 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448096 DCHECK(!ShouldDeferReads());
[email protected]370eaf12013-05-18 09:19:498097 TextureRef* texture_ref = GetTextureInfoForTarget(target);
8098 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518099 LOCAL_SET_GL_ERROR(
8100 GL_INVALID_OPERATION,
8101 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438102 return;
8103 }
[email protected]370eaf12013-05-18 09:19:498104 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438105 GLenum type = 0;
8106 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078107 if (!texture->GetLevelType(target, level, &type, &format) ||
8108 !texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438109 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518110 LOCAL_SET_GL_ERROR(
8111 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438112 return;
8113 }
[email protected]85a4ac22013-05-31 01:58:478114 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518115 LOCAL_SET_GL_ERROR(
8116 GL_INVALID_OPERATION,
8117 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598118 return;
8119 }
[email protected]9edc6b22010-12-23 02:00:268120
8121 // Check we have compatible formats.
8122 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8123 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8124 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8125
[email protected]2d3765b2012-10-03 00:31:078126 if (!channels_needed ||
8127 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518128 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438129 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268130 return;
8131 }
8132
[email protected]81375742012-06-08 00:04:008133 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518134 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008135 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438136 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008137 return;
8138 }
8139
[email protected]a0b78dc2011-11-11 10:43:108140 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8141 return;
8142 }
8143
[email protected]de26b3c2011-08-03 21:54:278144 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038145 gfx::Size size = GetBoundReadFrameBufferSize();
8146 GLint copyX = 0;
8147 GLint copyY = 0;
8148 GLint copyWidth = 0;
8149 GLint copyHeight = 0;
8150 Clip(x, width, size.width(), &copyX, &copyWidth);
8151 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208152
[email protected]370eaf12013-05-18 09:19:498153 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:518154 LOCAL_SET_GL_ERROR(
8155 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208156 return;
8157 }
8158
[email protected]6e288612010-12-21 20:45:038159 if (copyX != x ||
8160 copyY != y ||
8161 copyWidth != width ||
8162 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208163 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038164 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348165 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248166 width, height, format, type, state_.unpack_alignment, &pixels_size,
8167 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518168 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438169 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038170 return;
8171 }
[email protected]40d90a22013-04-09 03:39:558172 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038173 memset(zero.get(), 0, pixels_size);
8174 glTexSubImage2D(
8175 target, level, xoffset, yoffset, width, height,
8176 format, type, zero.get());
8177 }
[email protected]0d6bfdc2011-11-02 01:32:208178
[email protected]6e288612010-12-21 20:45:038179 if (copyHeight > 0 && copyWidth > 0) {
8180 GLint dx = copyX - x;
8181 GLint dy = copyY - y;
8182 GLint destX = xoffset + dx;
8183 GLint destY = yoffset + dy;
8184 glCopyTexSubImage2D(target, level,
8185 destX, destY, copyX, copyY,
8186 copyWidth, copyHeight);
8187 }
[email protected]cadde4a2010-07-31 17:10:438188}
8189
[email protected]f598f422012-12-07 08:30:038190bool GLES2DecoderImpl::ValidateTexSubImage2D(
8191 error::Error* error,
8192 const char* function_name,
8193 GLenum target,
8194 GLint level,
8195 GLint xoffset,
8196 GLint yoffset,
8197 GLsizei width,
8198 GLsizei height,
8199 GLenum format,
8200 GLenum type,
8201 const void * data) {
8202 (*error) = error::kNoError;
8203 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518204 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038205 return false;
8206 }
8207 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518208 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038209 return false;
8210 }
8211 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518212 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038213 return false;
8214 }
8215 if (!validators_->texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518216 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]f598f422012-12-07 08:30:038217 return false;
8218 }
8219 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:518220 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]f598f422012-12-07 08:30:038221 return false;
8222 }
[email protected]370eaf12013-05-18 09:19:498223 TextureRef* texture_ref = GetTextureInfoForTarget(target);
8224 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518225 LOCAL_SET_GL_ERROR(
8226 GL_INVALID_OPERATION,
8227 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038228 return false;
[email protected]cadde4a2010-07-31 17:10:438229 }
[email protected]370eaf12013-05-18 09:19:498230 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:528231 GLenum current_type = 0;
8232 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078233 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518234 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038235 GL_INVALID_OPERATION, function_name, "level does not exist.");
8236 return false;
[email protected]df6cf1ad2011-01-29 01:20:528237 }
8238 if (format != internal_format) {
[email protected]ab09b612013-03-11 22:11:518239 LOCAL_SET_GL_ERROR(
8240 GL_INVALID_OPERATION,
8241 function_name, "format does not match internal format.");
[email protected]f598f422012-12-07 08:30:038242 return false;
[email protected]df6cf1ad2011-01-29 01:20:528243 }
8244 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518245 LOCAL_SET_GL_ERROR(
8246 GL_INVALID_OPERATION,
8247 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038248 return false;
[email protected]df6cf1ad2011-01-29 01:20:528249 }
[email protected]85a4ac22013-05-31 01:58:478250 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518251 LOCAL_SET_GL_ERROR(
8252 GL_INVALID_OPERATION,
8253 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598254 return false;
8255 }
[email protected]02965c22013-03-09 02:40:078256 if (!texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438257 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518258 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038259 return false;
[email protected]cadde4a2010-07-31 17:10:438260 }
[email protected]81375742012-06-08 00:04:008261 if ((GLES2Util::GetChannelsForFormat(format) &
8262 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518263 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008264 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038265 function_name, "can not supply data for depth or stencil textures");
8266 return false;
[email protected]81375742012-06-08 00:04:008267 }
[email protected]f598f422012-12-07 08:30:038268 if (data == NULL) {
8269 (*error) = error::kOutOfBounds;
8270 return false;
8271 }
8272 return true;
8273}
[email protected]81375742012-06-08 00:04:008274
[email protected]f598f422012-12-07 08:30:038275error::Error GLES2DecoderImpl::DoTexSubImage2D(
8276 GLenum target,
8277 GLint level,
8278 GLint xoffset,
8279 GLint yoffset,
8280 GLsizei width,
8281 GLsizei height,
8282 GLenum format,
8283 GLenum type,
8284 const void * data) {
8285 error::Error error = error::kNoError;
8286 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8287 xoffset, yoffset, width, height, format, type, data)) {
8288 return error;
8289 }
[email protected]370eaf12013-05-18 09:19:498290 TextureRef* texture_ref = GetTextureInfoForTarget(target);
8291 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:158292 GLsizei tex_width = 0;
8293 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078294 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:158295 DCHECK(ok);
8296 if (xoffset != 0 || yoffset != 0 ||
8297 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:498298 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
8299 target, level)) {
[email protected]ab09b612013-03-11 22:11:518300 LOCAL_SET_GL_ERROR(
8301 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038302 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308303 }
[email protected]63b465922012-09-06 02:04:528304 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158305 glTexSubImage2D(
8306 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038307 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208308 }
[email protected]4502e6492011-12-14 19:39:158309
[email protected]02965c22013-03-09 02:40:078310 if (teximage2d_faster_than_texsubimage2d_ && !texture->IsImmutable()) {
[email protected]63b465922012-09-06 02:04:528311 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158312 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
8313 // same as internal_foramt. If that changes we'll need to look them up.
[email protected]8f1d2aa2013-05-10 23:45:388314 glTexImage2D(
[email protected]4502e6492011-12-14 19:39:158315 target, level, format, width, height, 0, format, type, data);
8316 } else {
[email protected]63b465922012-09-06 02:04:528317 ScopedTextureUploadTimer timer(this);
[email protected]4502e6492011-12-14 19:39:158318 glTexSubImage2D(
8319 target, level, xoffset, yoffset, width, height, format, type, data);
8320 }
[email protected]370eaf12013-05-18 09:19:498321 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]f598f422012-12-07 08:30:038322 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438323}
8324
[email protected]b493ee622011-04-13 23:52:008325error::Error GLES2DecoderImpl::HandleTexSubImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358326 uint32 immediate_data_size, const cmds::TexSubImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388327 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
[email protected]b493ee622011-04-13 23:52:008328 GLboolean internal = static_cast<GLboolean>(c.internal);
8329 if (internal == GL_TRUE && tex_image_2d_failed_)
8330 return error::kNoError;
8331
8332 GLenum target = static_cast<GLenum>(c.target);
8333 GLint level = static_cast<GLint>(c.level);
8334 GLint xoffset = static_cast<GLint>(c.xoffset);
8335 GLint yoffset = static_cast<GLint>(c.yoffset);
8336 GLsizei width = static_cast<GLsizei>(c.width);
8337 GLsizei height = static_cast<GLsizei>(c.height);
8338 GLenum format = static_cast<GLenum>(c.format);
8339 GLenum type = static_cast<GLenum>(c.type);
8340 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348341 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248342 width, height, format, type, state_.unpack_alignment, &data_size,
8343 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008344 return error::kOutOfBounds;
8345 }
8346 const void* pixels = GetSharedMemoryAs<const void*>(
8347 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038348 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008349 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008350}
8351
8352error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate(
[email protected]ed9f9cd2013-02-27 21:12:358353 uint32 immediate_data_size, const cmds::TexSubImage2DImmediate& c) {
[email protected]b493ee622011-04-13 23:52:008354 GLboolean internal = static_cast<GLboolean>(c.internal);
8355 if (internal == GL_TRUE && tex_image_2d_failed_)
8356 return error::kNoError;
8357
8358 GLenum target = static_cast<GLenum>(c.target);
8359 GLint level = static_cast<GLint>(c.level);
8360 GLint xoffset = static_cast<GLint>(c.xoffset);
8361 GLint yoffset = static_cast<GLint>(c.yoffset);
8362 GLsizei width = static_cast<GLsizei>(c.width);
8363 GLsizei height = static_cast<GLsizei>(c.height);
8364 GLenum format = static_cast<GLenum>(c.format);
8365 GLenum type = static_cast<GLenum>(c.type);
8366 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348367 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248368 width, height, format, type, state_.unpack_alignment, &data_size,
8369 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008370 return error::kOutOfBounds;
8371 }
8372 const void* pixels = GetImmediateDataAs<const void*>(
8373 c, data_size, immediate_data_size);
[email protected]f598f422012-12-07 08:30:038374 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008375 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008376}
8377
[email protected]f7a64ee2010-02-01 22:24:148378error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]ed9f9cd2013-02-27 21:12:358379 uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:368380 GLuint index = static_cast<GLuint>(c.index);
8381 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:358382 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:258383 Result* result = GetSharedMemoryAs<Result*>(
8384 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:368385 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:148386 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:368387 }
[email protected]07d0cc82010-02-17 04:51:408388 // Check that the client initialized the result.
8389 if (result->size != 0) {
8390 return error::kInvalidArguments;
8391 }
[email protected]9438b012010-06-15 22:55:058392 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:518393 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8394 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:148395 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368396 }
[email protected]3916c97e2010-02-25 03:20:508397 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:518398 LOCAL_SET_GL_ERROR(
8399 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:148400 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368401 }
[email protected]0bfd9882010-02-05 23:02:258402 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:088403 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:358404 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:148405 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328406}
8407
[email protected]f7b85372010-02-03 01:11:378408bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:428409 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:378410 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:128411 error::Error* error, GLint* real_location,
8412 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:108413 DCHECK(error);
8414 DCHECK(service_id);
8415 DCHECK(result_pointer);
8416 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:128417 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:378418 *error = error::kNoError;
8419 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:258420 SizedResult<GLint>* result;
8421 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8422 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8423 if (!result) {
[email protected]f7b85372010-02-03 01:11:378424 *error = error::kOutOfBounds;
8425 return false;
8426 }
[email protected]0bfd9882010-02-05 23:02:258427 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:378428 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:258429 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:428430 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
8431 if (!program) {
[email protected]ae51d192010-04-27 00:48:038432 return false;
8433 }
[email protected]df37b9932013-03-08 05:21:428434 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:378435 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:518436 LOCAL_SET_GL_ERROR(
8437 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:378438 return false;
8439 }
[email protected]df37b9932013-03-08 05:21:428440 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:368441 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:358442 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428443 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:128444 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:368445 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:378446 // No such location.
[email protected]ab09b612013-03-11 22:11:518447 LOCAL_SET_GL_ERROR(
8448 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:378449 return false;
8450 }
[email protected]43c2f1f2011-03-25 18:35:368451 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:508452 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:378453 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:518454 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:378455 return false;
8456 }
[email protected]0bfd9882010-02-05 23:02:258457 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8458 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8459 if (!result) {
[email protected]f7b85372010-02-03 01:11:378460 *error = error::kOutOfBounds;
8461 return false;
8462 }
[email protected]0bfd9882010-02-05 23:02:258463 result->size = size;
[email protected]939e7362010-05-13 20:49:108464 *result_type = type;
[email protected]f7b85372010-02-03 01:11:378465 return true;
8466}
8467
[email protected]f7a64ee2010-02-01 22:24:148468error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]ed9f9cd2013-02-27 21:12:358469 uint32 immediate_data_size, const cmds::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:378470 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338471 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378472 GLuint service_id;
[email protected]939e7362010-05-13 20:49:108473 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:128474 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378475 Error error;
[email protected]0bfd9882010-02-05 23:02:258476 void* result;
[email protected]f7b85372010-02-03 01:11:378477 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128478 program, fake_location, c.params_shm_id, c.params_shm_offset,
8479 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:258480 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:128481 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:358482 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:378483 }
8484 return error;
[email protected]96449d2c2009-11-25 00:01:328485}
8486
[email protected]f7a64ee2010-02-01 22:24:148487error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]ed9f9cd2013-02-27 21:12:358488 uint32 immediate_data_size, const cmds::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:378489 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338490 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378491 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:128492 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378493 Error error;
[email protected]ed9f9cd2013-02-27 21:12:358494 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:108495 Result* result;
8496 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:378497 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128498 program, fake_location, c.params_shm_id, c.params_shm_offset,
8499 &error, &real_location, &service_id,
8500 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:108501 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8502 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8503 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:558504 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:128505 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:108506 GLfloat* dst = result->GetData();
8507 for (GLsizei ii = 0; ii < num_values; ++ii) {
8508 dst[ii] = (temp[ii] != 0);
8509 }
8510 } else {
[email protected]1b0a6752012-02-22 03:44:128511 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:108512 }
[email protected]f7b85372010-02-03 01:11:378513 }
8514 return error;
[email protected]96449d2c2009-11-25 00:01:328515}
8516
[email protected]f7a64ee2010-02-01 22:24:148517error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]ed9f9cd2013-02-27 21:12:358518 uint32 immediate_data_size, const cmds::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:258519 GLenum shader_type = static_cast<GLenum>(c.shadertype);
8520 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:358521 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:258522 Result* result = GetSharedMemoryAs<Result*>(
8523 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8524 if (!result) {
8525 return error::kOutOfBounds;
8526 }
[email protected]07d0cc82010-02-17 04:51:408527 // Check that the client initialized the result.
8528 if (result->success != 0) {
8529 return error::kInvalidArguments;
8530 }
[email protected]9438b012010-06-15 22:55:058531 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:518532 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538533 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:298534 return error::kNoError;
8535 }
[email protected]9438b012010-06-15 22:55:058536 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:518537 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538538 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:298539 return error::kNoError;
8540 }
8541
8542 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:408543
[email protected]46c86752013-05-21 05:08:398544 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:408545 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:218546 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:408547
8548 result->min_range = range[0];
8549 result->max_range = range[1];
8550 result->precision = precision;
8551
[email protected]f7a64ee2010-02-01 22:24:148552 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328553}
8554
[email protected]f7a64ee2010-02-01 22:24:148555error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]ed9f9cd2013-02-27 21:12:358556 uint32 immediate_data_size, const cmds::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:258557 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:428558 GLuint program_id = static_cast<GLuint>(c.program);
8559 Program* program = GetProgramInfoNotShader(
8560 program_id, "glGetAttachedShaders");
8561 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258562 return error::kNoError;
8563 }
[email protected]ed9f9cd2013-02-27 21:12:358564 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:258565 uint32 max_count = Result::ComputeMaxResults(result_size);
8566 Result* result = GetSharedMemoryAs<Result*>(
8567 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8568 if (!result) {
8569 return error::kOutOfBounds;
8570 }
[email protected]07d0cc82010-02-17 04:51:408571 // Check that the client initialized the result.
8572 if (result->size != 0) {
8573 return error::kInvalidArguments;
8574 }
[email protected]0bfd9882010-02-05 23:02:258575 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:038576 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:428577 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:258578 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:038579 if (!shader_manager()->GetClientId(result->GetData()[ii],
8580 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:258581 NOTREACHED();
8582 return error::kGenericError;
8583 }
8584 }
8585 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:148586 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328587}
8588
[email protected]f7a64ee2010-02-01 22:24:148589error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]ed9f9cd2013-02-27 21:12:358590 uint32 immediate_data_size, const cmds::GetActiveUniform& c) {
[email protected]df37b9932013-03-08 05:21:428591 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258592 GLuint index = c.index;
8593 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358594 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:258595 Result* result = GetSharedMemoryAs<Result*>(
8596 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8597 if (!result) {
8598 return error::kOutOfBounds;
8599 }
[email protected]07d0cc82010-02-17 04:51:408600 // Check that the client initialized the result.
8601 if (result->success != 0) {
8602 return error::kInvalidArguments;
8603 }
[email protected]df37b9932013-03-08 05:21:428604 Program* program = GetProgramInfoNotShader(
8605 program_id, "glGetActiveUniform");
8606 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258607 return error::kNoError;
8608 }
[email protected]ed9f9cd2013-02-27 21:12:358609 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428610 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:258611 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:518612 LOCAL_SET_GL_ERROR(
8613 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258614 return error::kNoError;
8615 }
8616 result->success = 1; // true.
8617 result->size = uniform_info->size;
8618 result->type = uniform_info->type;
8619 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298620 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148621 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328622}
8623
[email protected]f7a64ee2010-02-01 22:24:148624error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]ed9f9cd2013-02-27 21:12:358625 uint32 immediate_data_size, const cmds::GetActiveAttrib& c) {
[email protected]df37b9932013-03-08 05:21:428626 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258627 GLuint index = c.index;
8628 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358629 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:258630 Result* result = GetSharedMemoryAs<Result*>(
8631 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8632 if (!result) {
8633 return error::kOutOfBounds;
8634 }
[email protected]07d0cc82010-02-17 04:51:408635 // Check that the client initialized the result.
8636 if (result->success != 0) {
8637 return error::kInvalidArguments;
8638 }
[email protected]df37b9932013-03-08 05:21:428639 Program* program = GetProgramInfoNotShader(
8640 program_id, "glGetActiveAttrib");
8641 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258642 return error::kNoError;
8643 }
[email protected]ed9f9cd2013-02-27 21:12:358644 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:428645 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:258646 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:518647 LOCAL_SET_GL_ERROR(
8648 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258649 return error::kNoError;
8650 }
8651 result->success = 1; // true.
8652 result->size = attrib_info->size;
8653 result->type = attrib_info->type;
8654 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298655 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148656 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328657}
8658
[email protected]b273e432010-04-12 17:23:588659error::Error GLES2DecoderImpl::HandleShaderBinary(
[email protected]ed9f9cd2013-02-27 21:12:358660 uint32 immediate_data_size, const cmds::ShaderBinary& c) {
[email protected]b273e432010-04-12 17:23:588661#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:518662 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:588663 return error::kNoError;
8664#else
8665 GLsizei n = static_cast<GLsizei>(c.n);
8666 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:518667 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:588668 return error::kNoError;
8669 }
8670 GLsizei length = static_cast<GLsizei>(c.length);
8671 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:518672 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:588673 return error::kNoError;
8674 }
8675 uint32 data_size;
8676 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
8677 return error::kOutOfBounds;
8678 }
8679 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
8680 c.shaders_shm_id, c.shaders_shm_offset, data_size);
8681 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
8682 const void* binary = GetSharedMemoryAs<const void*>(
8683 c.binary_shm_id, c.binary_shm_offset, length);
8684 if (shaders == NULL || binary == NULL) {
8685 return error::kOutOfBounds;
8686 }
8687 scoped_array<GLuint> service_ids(new GLuint[n]);
8688 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:428689 Shader* shader = GetShader(shaders[ii]);
8690 if (!shader) {
[email protected]ab09b612013-03-11 22:11:518691 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:588692 return error::kNoError;
8693 }
[email protected]df37b9932013-03-08 05:21:428694 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:588695 }
8696 // TODO(gman): call glShaderBinary
8697 return error::kNoError;
8698#endif
8699}
8700
[email protected]6d792ee12013-05-15 00:40:568701void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:498702 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:088703
[email protected]64ace852011-05-19 21:49:498704 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:428705 // TRACE_EVENT for gpu tests:
8706 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:428707 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:428708 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
8709 "width", (is_offscreen ? offscreen_size_.width() :
8710 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:568711 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:498712 "offscreen", is_offscreen,
8713 "frame", this_frame_number);
[email protected]6217d392010-03-25 22:08:358714 // If offscreen then don't actually SwapBuffers to the display. Just copy
8715 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:498716 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:318717 TRACE_EVENT2("gpu", "Offscreen",
8718 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:538719 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
8720 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
8721 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
8722 // fix this.
[email protected]62e155e2012-10-23 22:43:158723 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:538724 offscreen_saved_frame_buffer_->Create();
8725 glFinish();
8726 }
8727
8728 // Allocate the offscreen saved color texture.
8729 DCHECK(offscreen_saved_color_format_);
8730 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:098731 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:538732
8733 offscreen_saved_frame_buffer_->AttachRenderTexture(
8734 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:058735 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
8736 if (offscreen_saved_frame_buffer_->CheckStatus() !=
8737 GL_FRAMEBUFFER_COMPLETE) {
8738 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
8739 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:568740 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
8741 return;
[email protected]f0cfe752013-01-14 01:09:058742 }
[email protected]1fb8c482011-08-31 01:01:538743
[email protected]f0cfe752013-01-14 01:09:058744 // Clear the offscreen color texture.
8745 // TODO(piman): Is this still necessary?
8746 {
8747 ScopedFrameBufferBinder binder(this,
8748 offscreen_saved_frame_buffer_->id());
8749 glClearColor(0, 0, 0, 0);
8750 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
8751 glDisable(GL_SCISSOR_TEST);
8752 glClear(GL_COLOR_BUFFER_BIT);
8753 RestoreClearState();
8754 }
[email protected]1fb8c482011-08-31 01:01:538755 }
8756
8757 UpdateParentTextureInfo();
8758 }
8759
[email protected]f0cfe752013-01-14 01:09:058760 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:568761 return;
[email protected]ab09b612013-03-11 22:11:518762 ScopedGLErrorSuppressor suppressor(
[email protected]6d792ee12013-05-15 00:40:568763 "GLES2DecoderImpl::DoSwapBuffers", this);
[email protected]6217d392010-03-25 22:08:358764
[email protected]34ff8b0c2010-10-01 20:06:028765 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:138766 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:278767 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:488768 } else {
[email protected]069944672012-04-25 20:52:238769 ScopedFrameBufferBinder binder(this,
8770 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:138771
[email protected]069944672012-04-25 20:52:238772 if (offscreen_target_buffer_preserved_) {
8773 // Copy the target frame buffer to the saved offscreen texture.
8774 offscreen_saved_color_texture_->Copy(
8775 offscreen_saved_color_texture_->size(),
8776 offscreen_saved_color_format_);
8777 } else {
8778 // Flip the textures in the parent context via the texture manager.
8779 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:498780 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:238781 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:568782
[email protected]069944672012-04-25 20:52:238783 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
8784 offscreen_target_frame_buffer_->AttachRenderTexture(
8785 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:488786 }
[email protected]069944672012-04-25 20:52:238787
8788 // Ensure the side effects of the copy are visible to the parent
8789 // context. There is no need to do this for ANGLE because it uses a
8790 // single D3D device for all contexts.
8791 if (!IsAngle())
8792 glFlush();
[email protected]0c8c9d22010-06-25 17:36:398793 }
[email protected]6217d392010-03-25 22:08:358794 } else {
[email protected]111975c62012-09-06 01:37:318795 TRACE_EVENT2("gpu", "Onscreen",
8796 "width", surface_->GetSize().width(),
8797 "height", surface_->GetSize().height());
[email protected]f62a5ab2011-05-23 20:34:158798 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:018799 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:568800 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:018801 }
[email protected]6217d392010-03-25 22:08:358802 }
[email protected]6217d392010-03-25 22:08:358803}
8804
[email protected]d4239852011-08-12 04:51:228805error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358806 uint32 immediate_data_size, const cmds::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:188807 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288808 if (!bucket || bucket->size() == 0) {
8809 return error::kInvalidArguments;
8810 }
[email protected]ed9f9cd2013-02-27 21:12:358811 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:188812 Result* result = GetSharedMemoryAs<Result*>(
8813 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8814 if (!result) {
8815 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:108816 }
[email protected]b1d2dcb2010-05-17 19:24:188817 // Check that the client initialized the result.
8818 if (*result != 0) {
8819 return error::kInvalidArguments;
8820 }
8821 std::string feature_str;
8822 if (!bucket->GetAsString(&feature_str)) {
8823 return error::kInvalidArguments;
8824 }
8825
8826 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:228827 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:188828 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:228829 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:408830 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
8831 // TODO(gman): decide how to remove the need for this const_cast.
8832 // I could make validators_ non const but that seems bad as this is the only
8833 // place it is needed. I could make some special friend class of validators
8834 // just to allow this to set them. That seems silly. I could refactor this
8835 // code to use the extension mechanism or the initialization attributes to
8836 // turn this feature on. Given that the only real point of this is to make
8837 // the conformance tests pass and given that there is lots of real work that
8838 // needs to be done it seems like refactoring for one to one of those
8839 // methods is a very low priority.
8840 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:048841 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
8842 force_webgl_glsl_validation_ = true;
8843 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:188844 } else {
8845 return error::kNoError;
8846 }
8847
8848 *result = 1; // true.
8849 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:108850}
8851
[email protected]c2f8c8402010-12-06 18:07:248852error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
8853 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:358854 const cmds::GetRequestableExtensionsCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:248855 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:358856 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]e82fb792011-09-22 00:33:298857 info->Initialize(disallowed_features_, NULL);
[email protected]c2f8c8402010-12-06 18:07:248858 bucket->SetFromString(info->extensions().c_str());
8859 return error::kNoError;
8860}
8861
8862error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358863 uint32 immediate_data_size, const cmds::RequestExtensionCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:248864 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288865 if (!bucket || bucket->size() == 0) {
8866 return error::kInvalidArguments;
8867 }
[email protected]c2f8c8402010-12-06 18:07:248868 std::string feature_str;
8869 if (!bucket->GetAsString(&feature_str)) {
8870 return error::kInvalidArguments;
8871 }
8872
[email protected]4b7eba92013-01-08 02:23:568873 bool desire_webgl_glsl_validation =
8874 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
8875 bool desire_standard_derivatives = false;
8876 if (force_webgl_glsl_validation_) {
8877 desire_standard_derivatives =
8878 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:048879 }
8880
[email protected]4b7eba92013-01-08 02:23:568881 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
8882 desire_standard_derivatives != derivatives_explicitly_enabled_) {
8883 force_webgl_glsl_validation_ = desire_webgl_glsl_validation;
8884 derivatives_explicitly_enabled_ = desire_standard_derivatives;
[email protected]c2f8c8402010-12-06 18:07:248885 InitializeShaderTranslator();
8886 }
8887
[email protected]302ce6d2011-07-07 23:28:118888 UpdateCapabilities();
8889
[email protected]c2f8c8402010-12-06 18:07:248890 return error::kNoError;
8891}
8892
[email protected]372e0412011-06-28 16:08:568893error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358894 uint32 immediate_data_size, const cmds::GetMultipleIntegervCHROMIUM& c) {
[email protected]372e0412011-06-28 16:08:568895 GLuint count = c.count;
8896 uint32 pnames_size;
8897 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
8898 return error::kOutOfBounds;
8899 }
8900 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
8901 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
8902 if (pnames == NULL) {
8903 return error::kOutOfBounds;
8904 }
8905
8906 // We have to copy them since we use them twice so the client
8907 // can't change them between the time we validate them and the time we use
8908 // them.
[email protected]40d90a22013-04-09 03:39:558909 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:568910 memcpy(enums.get(), pnames, pnames_size);
8911
8912 // Count up the space needed for the result.
8913 uint32 num_results = 0;
8914 for (GLuint ii = 0; ii < count; ++ii) {
8915 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
8916 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:518917 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8918 "glGetMulitpleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:568919 return error::kNoError;
8920 }
8921 // Num will never be more than 4.
8922 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:478923 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:568924 return error::kOutOfBounds;
8925 }
8926 }
8927
8928 uint32 result_size = 0;
8929 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
8930 return error::kOutOfBounds;
8931 }
8932
8933 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:518934 LOCAL_SET_GL_ERROR(
8935 GL_INVALID_VALUE,
8936 "glGetMulitpleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:568937 return error::kNoError;
8938 }
8939
8940 GLint* results = GetSharedMemoryAs<GLint*>(
8941 c.results_shm_id, c.results_shm_offset, result_size);
8942 if (results == NULL) {
8943 return error::kOutOfBounds;
8944 }
8945
8946 // Check the results have been cleared in case the context was lost.
8947 for (uint32 ii = 0; ii < num_results; ++ii) {
8948 if (results[ii]) {
8949 return error::kInvalidArguments;
8950 }
8951 }
8952
8953 // Get each result.
8954 GLint* start = results;
8955 for (GLuint ii = 0; ii < count; ++ii) {
8956 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:268957 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:538958 !GetHelper(enums[ii], results, &num_written)) {
[email protected]b0ce0982013-05-13 18:51:488959 DoGetIntegerv(enums[ii], results);
[email protected]372e0412011-06-28 16:08:568960 }
8961 results += num_written;
8962 }
8963
8964 // Just to verify. Should this be a DCHECK?
8965 if (static_cast<uint32>(results - start) != num_results) {
8966 return error::kOutOfBounds;
8967 }
8968
8969 return error::kNoError;
8970}
8971
[email protected]2318d342011-07-11 22:27:428972error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358973 uint32 immediate_data_size, const cmds::GetProgramInfoCHROMIUM& c) {
[email protected]df37b9932013-03-08 05:21:428974 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:428975 uint32 bucket_id = c.bucket_id;
8976 Bucket* bucket = CreateBucket(bucket_id);
8977 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:428978 Program* program = NULL;
8979 program = GetProgram(program_id);
8980 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:468981 return error::kNoError;
[email protected]2318d342011-07-11 22:27:428982 }
[email protected]df37b9932013-03-08 05:21:428983 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:428984 return error::kNoError;
8985}
8986
[email protected]38d139d2011-07-14 00:38:438987error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
8988 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:438989 case GL_NO_ERROR:
8990 // TODO(kbr): improve the precision of the error code in this case.
8991 // Consider delegating to context for error code if MakeCurrent fails.
8992 return error::kUnknown;
8993 case GL_GUILTY_CONTEXT_RESET_ARB:
8994 return error::kGuilty;
8995 case GL_INNOCENT_CONTEXT_RESET_ARB:
8996 return error::kInnocent;
8997 case GL_UNKNOWN_CONTEXT_RESET_ARB:
8998 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:438999 }
9000
9001 NOTREACHED();
9002 return error::kUnknown;
9003}
9004
9005bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099006 if (reset_status_ != GL_NO_ERROR) {
9007 return true;
9008 }
[email protected]706b69f2012-07-27 04:59:309009 if (context_->WasAllocatedUsingRobustnessExtension()) {
9010 GLenum status = GL_NO_ERROR;
9011 if (has_robustness_extension_)
9012 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439013 if (status != GL_NO_ERROR) {
9014 // The graphics card was reset. Signal a lost context to the application.
9015 reset_status_ = status;
9016 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099017 << " context lost via ARB/EXT_robustness. Reset status = "
9018 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:439019 return true;
9020 }
9021 }
9022 return false;
9023}
9024
[email protected]c4485aad62012-12-17 10:19:099025void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9026 // Only loses the context once.
9027 if (reset_status_ != GL_NO_ERROR) {
9028 return;
9029 }
9030
9031 // Marks this context as lost.
9032 reset_status_ = reset_status;
9033 current_decoder_error_ = error::kLostContext;
9034
9035 // Loses the parent's context.
9036 if (parent_) {
9037 parent_->LoseContext(reset_status);
9038 }
9039
9040 // Loses any child contexts.
9041 for (ChildList::iterator it = children_.begin();
9042 it != children_.end();
9043 ++it) {
9044 (*it)->LoseContext(reset_status);
9045 }
9046}
9047
9048error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359049 uint32 immediate_data_size, const cmds::LoseContextCHROMIUM& c) {
[email protected]c4485aad62012-12-17 10:19:099050 GLenum current = static_cast<GLenum>(c.current);
9051 GLenum other = static_cast<GLenum>(c.other);
9052 if (!validators_->reset_status.IsValid(current)) {
[email protected]ab09b612013-03-11 22:11:519053 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9054 "glLoseContextCHROMIUM", current, "current");
[email protected]c4485aad62012-12-17 10:19:099055 }
9056 if (!validators_->reset_status.IsValid(other)) {
[email protected]ab09b612013-03-11 22:11:519057 LOCAL_SET_GL_ERROR_INVALID_ENUM("glLoseContextCHROMIUM", other, "other");
[email protected]c4485aad62012-12-17 10:19:099058 }
9059 group_->LoseContexts(other);
9060 reset_status_ = current;
9061 current_decoder_error_ = error::kLostContext;
9062 return error::kLostContext;
9063}
9064
[email protected]b096d032013-03-08 03:08:019065error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
9066 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) {
9067 return error::kUnknownCommand;
9068}
9069
[email protected]840a7e462013-02-27 01:29:519070error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359071 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) {
[email protected]840a7e462013-02-27 01:29:519072 if (wait_sync_point_callback_.is_null())
9073 return error::kNoError;
9074
9075 return wait_sync_point_callback_.Run(c.sync_point) ?
9076 error::kNoError : error::kDeferCommandUntilLater;
9077}
9078
[email protected]882ba1e22012-03-08 19:02:539079bool GLES2DecoderImpl::GenQueriesEXTHelper(
9080 GLsizei n, const GLuint* client_ids) {
9081 for (GLsizei ii = 0; ii < n; ++ii) {
9082 if (query_manager_->GetQuery(client_ids[ii])) {
9083 return false;
9084 }
9085 }
[email protected]c45f1972012-03-14 07:27:369086 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
[email protected]882ba1e22012-03-08 19:02:539087 return true;
9088}
9089
9090void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9091 GLsizei n, const GLuint* client_ids) {
9092 for (GLsizei ii = 0; ii < n; ++ii) {
9093 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9094 if (query && !query->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:249095 if (query == state_.current_query) {
9096 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539097 }
[email protected]c45f1972012-03-14 07:27:369098 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539099 query_manager_->RemoveQuery(client_ids[ii]);
9100 }
9101 }
9102}
9103
[email protected]22e3f552012-03-13 01:54:199104bool GLES2DecoderImpl::ProcessPendingQueries() {
9105 if (query_manager_.get() == NULL) {
9106 return false;
9107 }
[email protected]c45f1972012-03-14 07:27:369108 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:199109 current_decoder_error_ = error::kOutOfBounds;
9110 }
9111 return query_manager_->HavePendingQueries();
9112}
9113
[email protected]2b1767cf2013-03-16 09:25:059114bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]85a4ac22013-05-31 01:58:479115 return GetAsyncPixelTransferDelegate()->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059116}
9117
9118void GLES2DecoderImpl::PerformIdleWork() {
[email protected]85a4ac22013-05-31 01:58:479119 if (!GetAsyncPixelTransferDelegate()->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:059120 return;
[email protected]85a4ac22013-05-31 01:58:479121 GetAsyncPixelTransferDelegate()->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059122 ProcessFinishedAsyncTransfers();
9123}
9124
[email protected]882ba1e22012-03-08 19:02:539125error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359126 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539127 GLenum target = static_cast<GLenum>(c.target);
9128 GLuint client_id = static_cast<GLuint>(c.id);
9129 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9130 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9131
[email protected]c45f1972012-03-14 07:27:369132 switch (target) {
9133 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559134 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]0713f43d2012-12-14 22:41:309135 case GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009136 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369137 break;
9138 default:
[email protected]62e155e2012-10-23 22:43:159139 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519140 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009141 GL_INVALID_OPERATION, "glBeginQueryEXT",
9142 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369143 return error::kNoError;
9144 }
9145 break;
[email protected]882ba1e22012-03-08 19:02:539146 }
9147
[email protected]e259eb412012-10-13 05:47:249148 if (state_.current_query) {
[email protected]ab09b612013-03-11 22:11:519149 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439150 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539151 return error::kNoError;
9152 }
9153
9154 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519155 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539156 return error::kNoError;
9157 }
9158
9159 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9160 if (!query) {
[email protected]c45f1972012-03-14 07:27:369161 // TODO(gman): Decide if we need this check.
9162 //
[email protected]882ba1e22012-03-08 19:02:539163 // Checks id was made by glGenQueries
[email protected]c45f1972012-03-14 07:27:369164 //
9165 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
9166 // for all Query ids but from the POV of the command buffer service maybe
9167 // you don't.
9168 //
9169 // The client can enforce this. I don't think the service cares.
9170 //
9171 // IdAllocatorInterface* id_allocator =
9172 // group_->GetIdAllocator(id_namespaces::kQueries);
9173 // if (!id_allocator->InUse(client_id)) {
[email protected]ab09b612013-03-11 22:11:519174 // LOCAL_SET_GL_ERROR(
9175 // GL_INVALID_OPERATION,
9176 // "glBeginQueryEXT", "id not made by glGenQueriesEXT");
[email protected]c45f1972012-03-14 07:27:369177 // return error::kNoError;
9178 // }
9179 query = query_manager_->CreateQuery(
9180 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539181 }
9182
[email protected]c45f1972012-03-14 07:27:369183 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519184 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439185 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539186 return error::kNoError;
9187 } else if (query->shm_id() != sync_shm_id ||
9188 query->shm_offset() != sync_shm_offset) {
9189 DLOG(ERROR) << "Shared memory used by query not the same as before";
9190 return error::kInvalidArguments;
9191 }
9192
[email protected]c45f1972012-03-14 07:27:369193 if (!query_manager_->BeginQuery(query)) {
9194 return error::kOutOfBounds;
9195 }
[email protected]882ba1e22012-03-08 19:02:539196
[email protected]e259eb412012-10-13 05:47:249197 state_.current_query = query;
[email protected]882ba1e22012-03-08 19:02:539198 return error::kNoError;
9199}
9200
9201error::Error GLES2DecoderImpl::HandleEndQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359202 uint32 immediate_data_size, const cmds::EndQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539203 GLenum target = static_cast<GLenum>(c.target);
9204 uint32 submit_count = static_cast<GLuint>(c.submit_count);
9205
[email protected]e259eb412012-10-13 05:47:249206 if (!state_.current_query) {
[email protected]ab09b612013-03-11 22:11:519207 LOCAL_SET_GL_ERROR(
9208 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539209 return error::kNoError;
9210 }
[email protected]e259eb412012-10-13 05:47:249211 if (state_.current_query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519212 LOCAL_SET_GL_ERROR(
9213 GL_INVALID_OPERATION,
9214 "glEndQueryEXT", "target does not match active query");
[email protected]882ba1e22012-03-08 19:02:539215 return error::kNoError;
9216 }
[email protected]882ba1e22012-03-08 19:02:539217
[email protected]e259eb412012-10-13 05:47:249218 if (!query_manager_->EndQuery(state_.current_query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:369219 return error::kOutOfBounds;
9220 }
9221
[email protected]fe8d73c2013-02-16 22:37:329222 query_manager_->ProcessPendingTransferQueries();
9223
[email protected]e259eb412012-10-13 05:47:249224 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539225 return error::kNoError;
9226}
9227
[email protected]944b62f32012-09-27 02:20:469228bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9229 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469230 for (GLsizei ii = 0; ii < n; ++ii) {
9231 if (GetVertexAttribManager(client_ids[ii])) {
9232 return false;
9233 }
9234 }
[email protected]ab4fd7282012-10-12 16:25:579235
[email protected]62e155e2012-10-23 22:43:159236 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579237 // Emulated VAO
9238 for (GLsizei ii = 0; ii < n; ++ii) {
9239 CreateVertexAttribManager(client_ids[ii], 0);
9240 }
9241 } else {
[email protected]40d90a22013-04-09 03:39:559242 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:579243
9244 glGenVertexArraysOES(n, service_ids.get());
9245 for (GLsizei ii = 0; ii < n; ++ii) {
9246 CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
9247 }
[email protected]944b62f32012-09-27 02:20:469248 }
[email protected]ab4fd7282012-10-12 16:25:579249
[email protected]944b62f32012-09-27 02:20:469250 return true;
9251}
9252
9253void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9254 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469255 for (GLsizei ii = 0; ii < n; ++ii) {
9256 VertexAttribManager* vao =
9257 GetVertexAttribManager(client_ids[ii]);
9258 if (vao && !vao->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:249259 if (state_.vertex_attrib_manager == vao) {
9260 state_.vertex_attrib_manager = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469261 }
9262 RemoveVertexAttribManager(client_ids[ii]);
9263 }
9264 }
9265}
9266
9267void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469268 VertexAttribManager* vao = NULL;
9269 GLuint service_id = 0;
9270 if (client_id != 0) {
9271 vao = GetVertexAttribManager(client_id);
9272 if (!vao) {
9273 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9274 // only allows names that have been previously generated. As such, we do
9275 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:519276 LOCAL_SET_GL_ERROR(
9277 GL_INVALID_OPERATION,
9278 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:469279 current_decoder_error_ = error::kNoError;
9280 return;
9281 } else {
9282 service_id = vao->service_id();
9283 }
[email protected]944b62f32012-09-27 02:20:469284 } else {
[email protected]ab4fd7282012-10-12 16:25:579285 vao = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469286 }
9287
[email protected]ab4fd7282012-10-12 16:25:579288 // Only set the VAO state if it's changed
[email protected]e259eb412012-10-13 05:47:249289 if (state_.vertex_attrib_manager != vao) {
9290 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:159291 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579292 EmulateVertexArrayState();
9293 } else {
9294 glBindVertexArrayOES(service_id);
9295 }
9296 }
9297}
9298
9299// Used when OES_vertex_array_object isn't natively supported
9300void GLES2DecoderImpl::EmulateVertexArrayState() {
9301 // Setup the Vertex attribute state
9302 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
9303 RestoreStateForAttrib(vv);
9304 }
9305
9306 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:219307 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:249308 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:579309 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9310 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:469311}
9312
9313bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469314 const VertexAttribManager* vao =
9315 GetVertexAttribManager(client_id);
9316 return vao && vao->IsValid() && !vao->IsDeleted();
9317}
9318
[email protected]b0af4f52011-09-28 22:04:429319error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM(
9320 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359321 const cmds::CreateStreamTextureCHROMIUM& c) {
[email protected]62e155e2012-10-23 22:43:159322 if (!features().chromium_stream_texture) {
[email protected]ab09b612013-03-11 22:11:519323 LOCAL_SET_GL_ERROR(
9324 GL_INVALID_OPERATION,
9325 "glOpenStreamTextureCHROMIUM", "not supported.");
[email protected]b0af4f52011-09-28 22:04:429326 return error::kNoError;
9327 }
9328
9329 uint32 client_id = c.client_id;
[email protected]ed9f9cd2013-02-27 21:12:359330 typedef cmds::CreateStreamTextureCHROMIUM::Result Result;
[email protected]b0af4f52011-09-28 22:04:429331 Result* result = GetSharedMemoryAs<Result*>(
9332 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9333
[email protected]e5081262012-01-05 23:09:039334 if (!result)
9335 return error::kOutOfBounds;
[email protected]b0af4f52011-09-28 22:04:429336 *result = GL_ZERO;
[email protected]370eaf12013-05-18 09:19:499337 TextureRef* texture_ref = texture_manager()->GetTexture(client_id);
9338 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519339 LOCAL_SET_GL_ERROR(
9340 GL_INVALID_VALUE,
9341 "glCreateStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429342 return error::kNoError;
9343 }
9344
[email protected]370eaf12013-05-18 09:19:499345 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079346 if (texture->IsStreamTexture()) {
[email protected]ab09b612013-03-11 22:11:519347 LOCAL_SET_GL_ERROR(
9348 GL_INVALID_OPERATION,
9349 "glCreateStreamTextureCHROMIUM", "is already a stream texture.");
[email protected]b0af4f52011-09-28 22:04:429350 return error::kNoError;
9351 }
9352
[email protected]02965c22013-03-09 02:40:079353 if (texture->target() && texture->target() != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:519354 LOCAL_SET_GL_ERROR(
9355 GL_INVALID_OPERATION,
9356 "glCreateStreamTextureCHROMIUM",
9357 "is already bound to incompatible target.");
[email protected]b0af4f52011-09-28 22:04:429358 return error::kNoError;
9359 }
9360
9361 if (!stream_texture_manager_)
9362 return error::kInvalidArguments;
9363
9364 GLuint object_id = stream_texture_manager_->CreateStreamTexture(
[email protected]02965c22013-03-09 02:40:079365 texture->service_id(), client_id);
[email protected]b0af4f52011-09-28 22:04:429366
9367 if (object_id) {
[email protected]370eaf12013-05-18 09:19:499368 texture_manager()->SetStreamTexture(texture_ref, true);
[email protected]b0af4f52011-09-28 22:04:429369 } else {
[email protected]ab09b612013-03-11 22:11:519370 LOCAL_SET_GL_ERROR(
9371 GL_OUT_OF_MEMORY,
9372 "glCreateStreamTextureCHROMIUM", "failed to create platform texture.");
[email protected]b0af4f52011-09-28 22:04:429373 }
9374
9375 *result = object_id;
9376 return error::kNoError;
9377}
9378
9379error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM(
9380 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359381 const cmds::DestroyStreamTextureCHROMIUM& c) {
[email protected]b0af4f52011-09-28 22:04:429382 GLuint client_id = c.texture;
[email protected]370eaf12013-05-18 09:19:499383 TextureRef* texture_ref = texture_manager()->GetTexture(client_id);
9384 if (texture_ref && texture_ref->texture()->IsStreamTexture()) {
[email protected]b0af4f52011-09-28 22:04:429385 if (!stream_texture_manager_)
9386 return error::kInvalidArguments;
9387
[email protected]370eaf12013-05-18 09:19:499388 stream_texture_manager_->DestroyStreamTexture(texture_ref->service_id());
9389 texture_manager()->SetStreamTexture(texture_ref, false);
[email protected]b0af4f52011-09-28 22:04:429390 } else {
[email protected]ab09b612013-03-11 22:11:519391 LOCAL_SET_GL_ERROR(
9392 GL_INVALID_VALUE,
9393 "glDestroyStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429394 }
9395
9396 return error::kNoError;
9397}
9398
[email protected]e51bdf32011-11-23 22:21:469399#if defined(OS_MACOSX)
9400void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9401 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9402 texture_id);
9403 if (it != texture_to_io_surface_map_.end()) {
9404 // Found a previous IOSurface bound to this texture; release it.
9405 CFTypeRef surface = it->second;
9406 CFRelease(surface);
9407 texture_to_io_surface_map_.erase(it);
9408 }
9409}
9410#endif
9411
9412void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9413 GLenum target, GLsizei width, GLsizei height,
9414 GLuint io_surface_id, GLuint plane) {
9415#if defined(OS_MACOSX)
9416 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:519417 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439418 GL_INVALID_OPERATION,
9419 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:469420 return;
9421 }
9422
9423 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize();
9424 if (!surface_support) {
[email protected]ab09b612013-03-11 22:11:519425 LOCAL_SET_GL_ERROR(
9426 GL_INVALID_OPERATION,
9427 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6.");
[email protected]e51bdf32011-11-23 22:21:469428 return;
9429 }
9430
9431 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9432 // This might be supported in the future, and if we could require
9433 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9434 // could delete a lot of code. For now, perform strict validation so we
9435 // know what's going on.
[email protected]ab09b612013-03-11 22:11:519436 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469437 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439438 "glTexImageIOSurface2DCHROMIUM",
9439 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:469440 return;
9441 }
9442
[email protected]09d50362012-10-18 20:54:379443 // Default target might be conceptually valid, but disallow it to avoid
9444 // accidents.
[email protected]370eaf12013-05-18 09:19:499445 TextureRef* texture_ref = GetTextureInfoForTargetUnlessDefault(target);
9446 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519447 LOCAL_SET_GL_ERROR(
9448 GL_INVALID_OPERATION,
9449 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:469450 return;
9451 }
[email protected]e51bdf32011-11-23 22:21:469452
9453 // Look up the new IOSurface. Note that because of asynchrony
9454 // between processes this might fail; during live resizing the
9455 // plugin process might allocate and release an IOSurface before
9456 // this process gets a chance to look it up. Hold on to any old
9457 // IOSurface in this case.
9458 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id);
9459 if (!surface) {
[email protected]ab09b612013-03-11 22:11:519460 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439461 GL_INVALID_OPERATION,
9462 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:469463 return;
9464 }
9465
9466 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:499467 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:469468
9469 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9470 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:499471 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:469472
9473 CGLContextObj context =
9474 static_cast<CGLContextObj>(context_->GetHandle());
9475
9476 CGLError err = surface_support->CGLTexImageIOSurface2D(
9477 context,
9478 target,
9479 GL_RGBA,
9480 width,
9481 height,
9482 GL_BGRA,
9483 GL_UNSIGNED_INT_8_8_8_8_REV,
9484 surface,
9485 plane);
9486
9487 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:519488 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469489 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439490 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:469491 return;
9492 }
9493
9494 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499495 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:469496 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9497
9498#else
[email protected]ab09b612013-03-11 22:11:519499 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439500 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:469501#endif
9502}
9503
[email protected]97dc7cbe2011-12-06 17:26:179504static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9505 switch (internalformat) {
9506 case GL_RGB565:
9507 return GL_RGB;
9508 case GL_RGBA4:
9509 return GL_RGBA;
9510 case GL_RGB5_A1:
9511 return GL_RGBA;
9512 case GL_RGB8_OES:
9513 return GL_RGB;
9514 case GL_RGBA8_OES:
9515 return GL_RGBA;
9516 case GL_LUMINANCE8_ALPHA8_EXT:
9517 return GL_LUMINANCE_ALPHA;
9518 case GL_LUMINANCE8_EXT:
9519 return GL_LUMINANCE;
9520 case GL_ALPHA8_EXT:
9521 return GL_ALPHA;
9522 case GL_RGBA32F_EXT:
9523 return GL_RGBA;
9524 case GL_RGB32F_EXT:
9525 return GL_RGB;
9526 case GL_ALPHA32F_EXT:
9527 return GL_ALPHA;
9528 case GL_LUMINANCE32F_EXT:
9529 return GL_LUMINANCE;
9530 case GL_LUMINANCE_ALPHA32F_EXT:
9531 return GL_LUMINANCE_ALPHA;
9532 case GL_RGBA16F_EXT:
9533 return GL_RGBA;
9534 case GL_RGB16F_EXT:
9535 return GL_RGB;
9536 case GL_ALPHA16F_EXT:
9537 return GL_ALPHA;
9538 case GL_LUMINANCE16F_EXT:
9539 return GL_LUMINANCE;
9540 case GL_LUMINANCE_ALPHA16F_EXT:
9541 return GL_LUMINANCE_ALPHA;
9542 case GL_BGRA8_EXT:
9543 return GL_BGRA_EXT;
9544 default:
9545 return GL_NONE;
9546 }
9547}
9548
[email protected]43410e92012-04-20 17:06:289549void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:039550 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:549551 GLenum internal_format, GLenum dest_type) {
[email protected]370eaf12013-05-18 09:19:499552 TextureRef* dest_texture_ref = GetTexture(dest_id);
9553 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:289554
[email protected]370eaf12013-05-18 09:19:499555 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:519556 LOCAL_SET_GL_ERROR(
9557 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:289558 return;
9559 }
9560
9561 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:519562 LOCAL_SET_GL_ERROR(
9563 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:289564 return;
9565 }
9566
[email protected]370eaf12013-05-18 09:19:499567 Texture* source_texture = source_texture_ref->texture();
9568 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079569 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:259570 (source_texture->target() != GL_TEXTURE_2D &&
9571 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]ab09b612013-03-11 22:11:519572 LOCAL_SET_GL_ERROR(
9573 GL_INVALID_VALUE,
9574 "glCopyTextureCHROMIUM", "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:039575 return;
9576 }
9577
[email protected]43410e92012-04-20 17:06:289578 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:289579
[email protected]9bc9a2e82013-04-03 03:56:259580 if (source_texture->target() == GL_TEXTURE_2D) {
9581 if (!source_texture->GetLevelSize(GL_TEXTURE_2D, 0, &source_width,
9582 &source_height)) {
9583 LOCAL_SET_GL_ERROR(
9584 GL_INVALID_VALUE,
9585 "glCopyTextureChromium", "source texture has no level 0");
9586 return;
9587 }
9588
9589 // Check that this type of texture is allowed.
9590 if (!texture_manager()->ValidForTarget(GL_TEXTURE_2D, level, source_width,
9591 source_height, 1)) {
9592 LOCAL_SET_GL_ERROR(
9593 GL_INVALID_VALUE,
9594 "glCopyTextureCHROMIUM", "Bad dimensions");
9595 return;
9596 }
[email protected]43410e92012-04-20 17:06:289597 }
9598
[email protected]377976552013-05-14 23:32:569599 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9600 DCHECK(stream_texture_manager_);
9601 StreamTexture* stream_tex =
9602 stream_texture_manager_->LookupStreamTexture(
9603 source_texture->service_id());
9604 if (!stream_tex) {
9605 LOCAL_SET_GL_ERROR(
9606 GL_INVALID_VALUE,
9607 "glCopyTextureChromium", "Stream texture lookup failed");
9608 return;
9609 }
9610 gfx::Size size = stream_tex->GetSize();
9611 source_width = size.width();
9612 source_height = size.height();
9613 if (source_width <= 0 || source_height <= 0) {
9614 LOCAL_SET_GL_ERROR(
9615 GL_INVALID_VALUE,
9616 "glCopyTextureChromium", "invalid streamtexture size");
9617 return;
9618 }
9619 }
9620
[email protected]cf6b8f62012-05-25 21:43:379621 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9622 // needed because it takes 10s of milliseconds to initialize.
9623 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:519624 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:379625 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:279626 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:379627 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:519628 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:379629 return;
9630 }
9631
[email protected]a4a6bdd12013-04-19 20:46:549632 GLenum dest_type_previous;
[email protected]0a1e9ad2012-05-04 21:13:039633 GLenum dest_internal_format;
[email protected]02965c22013-03-09 02:40:079634 bool dest_level_defined = dest_texture->GetLevelSize(
9635 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:289636
[email protected]0a1e9ad2012-05-04 21:13:039637 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:549638 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:079639 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:039640 }
9641
[email protected]0a1e9ad2012-05-04 21:13:039642 // Resize the destination texture to the dimensions of the source texture.
9643 if (!dest_level_defined || dest_width != source_width ||
9644 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:549645 dest_internal_format != internal_format ||
9646 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:289647 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:519648 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:079649 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:389650 glTexImage2D(
[email protected]43410e92012-04-20 17:06:289651 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:039652 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:519653 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:039654 if (error != GL_NO_ERROR) {
9655 RestoreCurrentTexture2DBindings();
[email protected]43410e92012-04-20 17:06:289656 return;
[email protected]0a1e9ad2012-05-04 21:13:039657 }
[email protected]43410e92012-04-20 17:06:289658
9659 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499660 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:039661 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:259662 } else {
[email protected]02965c22013-03-09 02:40:079663 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:499664 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:289665 }
9666
[email protected]5394a4102013-04-18 05:41:379667 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
9668 // before presenting.
9669 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9670 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
9671 // instead of using default matrix crbug.com/226218.
9672 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
9673 0.0f, 1.0f, 0.0f, 0.0f,
9674 0.0f, 0.0f, 1.0f, 0.0f,
9675 0.0f, 0.0f, 0.0f, 1.0f};
9676 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
9677 this,
9678 source_texture->target(),
9679 dest_texture->target(),
9680 source_texture->service_id(),
9681 dest_texture->service_id(), level,
9682 source_width, source_height,
9683 unpack_flip_y_,
9684 unpack_premultiply_alpha_,
9685 unpack_unpremultiply_alpha_,
9686 default_matrix);
9687 } else {
9688 copy_texture_CHROMIUM_->DoCopyTexture(
9689 this,
9690 source_texture->target(),
9691 dest_texture->target(),
9692 source_texture->service_id(),
9693 dest_texture->service_id(), level,
9694 source_width, source_height,
9695 unpack_flip_y_,
9696 unpack_premultiply_alpha_,
9697 unpack_unpremultiply_alpha_);
9698 }
[email protected]43410e92012-04-20 17:06:289699}
9700
[email protected]97dc7cbe2011-12-06 17:26:179701static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
9702 switch (internalformat) {
9703 case GL_RGB565:
9704 return GL_UNSIGNED_SHORT_5_6_5;
9705 case GL_RGBA4:
9706 return GL_UNSIGNED_SHORT_4_4_4_4;
9707 case GL_RGB5_A1:
9708 return GL_UNSIGNED_SHORT_5_5_5_1;
9709 case GL_RGB8_OES:
9710 return GL_UNSIGNED_BYTE;
9711 case GL_RGBA8_OES:
9712 return GL_UNSIGNED_BYTE;
9713 case GL_LUMINANCE8_ALPHA8_EXT:
9714 return GL_UNSIGNED_BYTE;
9715 case GL_LUMINANCE8_EXT:
9716 return GL_UNSIGNED_BYTE;
9717 case GL_ALPHA8_EXT:
9718 return GL_UNSIGNED_BYTE;
9719 case GL_RGBA32F_EXT:
9720 return GL_FLOAT;
9721 case GL_RGB32F_EXT:
9722 return GL_FLOAT;
9723 case GL_ALPHA32F_EXT:
9724 return GL_FLOAT;
9725 case GL_LUMINANCE32F_EXT:
9726 return GL_FLOAT;
9727 case GL_LUMINANCE_ALPHA32F_EXT:
9728 return GL_FLOAT;
9729 case GL_RGBA16F_EXT:
9730 return GL_HALF_FLOAT_OES;
9731 case GL_RGB16F_EXT:
9732 return GL_HALF_FLOAT_OES;
9733 case GL_ALPHA16F_EXT:
9734 return GL_HALF_FLOAT_OES;
9735 case GL_LUMINANCE16F_EXT:
9736 return GL_HALF_FLOAT_OES;
9737 case GL_LUMINANCE_ALPHA16F_EXT:
9738 return GL_HALF_FLOAT_OES;
9739 case GL_BGRA8_EXT:
9740 return GL_UNSIGNED_BYTE;
9741 default:
9742 return GL_NONE;
9743 }
9744}
9745
9746void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:449747 GLenum target,
9748 GLint levels,
9749 GLenum internal_format,
9750 GLsizei width,
9751 GLsizei height) {
[email protected]43ed3a72012-05-30 22:55:389752 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT");
[email protected]80eb6b52012-01-19 00:14:419753 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]97dc7cbe2011-12-06 17:26:179754 TextureManager::ComputeMipMapCount(width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:519755 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439756 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:179757 return;
9758 }
[email protected]370eaf12013-05-18 09:19:499759 TextureRef* texture_ref = GetTextureInfoForTarget(target);
9760 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519761 LOCAL_SET_GL_ERROR(
9762 GL_INVALID_OPERATION,
9763 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:179764 return;
9765 }
[email protected]370eaf12013-05-18 09:19:499766 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079767 if (texture->IsAttachedToFramebuffer()) {
[email protected]88a61bf2012-10-27 13:00:429768 clear_state_dirty_ = true;
[email protected]97dc7cbe2011-12-06 17:26:179769 }
[email protected]02965c22013-03-09 02:40:079770 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519771 LOCAL_SET_GL_ERROR(
9772 GL_INVALID_OPERATION,
9773 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:179774 return;
9775 }
[email protected]7989c9e2013-01-23 06:39:269776
9777 GLenum format = ExtractFormatFromStorageFormat(internal_format);
9778 GLenum type = ExtractTypeFromStorageFormat(internal_format);
9779
9780 {
9781 GLsizei level_width = width;
9782 GLsizei level_height = height;
9783 uint32 estimated_size = 0;
9784 for (int ii = 0; ii < levels; ++ii) {
9785 uint32 level_size = 0;
9786 if (!GLES2Util::ComputeImageDataSizes(
9787 level_width, level_height, format, type, state_.unpack_alignment,
9788 &estimated_size, NULL, NULL) ||
9789 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519790 LOCAL_SET_GL_ERROR(
9791 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269792 return;
9793 }
9794 level_width = std::max(1, level_width >> 1);
9795 level_height = std::max(1, level_height >> 1);
9796 }
9797 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519798 LOCAL_SET_GL_ERROR(
9799 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:269800 return;
9801 }
9802 }
9803
[email protected]ab09b612013-03-11 22:11:519804 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:389805 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:519806 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:179807 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:159808 GLsizei level_width = width;
9809 GLsizei level_height = height;
9810 for (int ii = 0; ii < levels; ++ii) {
9811 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499812 texture_ref, target, ii, format,
9813 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:159814 level_width = std::max(1, level_width >> 1);
9815 level_height = std::max(1, level_height >> 1);
9816 }
[email protected]02965c22013-03-09 02:40:079817 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:179818 }
[email protected]97dc7cbe2011-12-06 17:26:179819}
[email protected]e51bdf32011-11-23 22:21:469820
[email protected]78b514b2012-05-01 21:50:599821error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359822 uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) {
[email protected]78b514b2012-05-01 21:50:599823 MailboxName name;
9824 mailbox_manager()->GenerateMailboxName(&name);
9825 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
9826 Bucket* bucket = CreateBucket(bucket_id);
9827
9828 bucket->SetSize(GL_MAILBOX_SIZE_CHROMIUM);
9829 bucket->SetData(&name, 0, GL_MAILBOX_SIZE_CHROMIUM);
9830
9831 return error::kNoError;
9832}
9833
9834void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
9835 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:029836 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:329837 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:029838 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
9839
[email protected]370eaf12013-05-18 09:19:499840 TextureRef* texture_ref = GetTextureInfoForTarget(target);
9841 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519842 LOCAL_SET_GL_ERROR(
9843 GL_INVALID_OPERATION,
9844 "glProduceTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599845 return;
9846 }
9847
[email protected]62e65f02013-05-29 22:28:109848 Texture* produced = texture_manager()->Produce(texture_ref);
9849 if (!produced) {
[email protected]ab09b612013-03-11 22:11:519850 LOCAL_SET_GL_ERROR(
9851 GL_INVALID_OPERATION,
9852 "glProduceTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599853 return;
9854 }
9855
9856 if (!group_->mailbox_manager()->ProduceTexture(
9857 target,
9858 *reinterpret_cast<const MailboxName*>(mailbox),
[email protected]62e65f02013-05-29 22:28:109859 produced)) {
[email protected]ab09b612013-03-11 22:11:519860 LOCAL_SET_GL_ERROR(
9861 GL_INVALID_OPERATION,
9862 "glProduceTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599863 return;
9864 }
[email protected]78b514b2012-05-01 21:50:599865}
9866
9867void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
9868 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:029869 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:329870 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:029871 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
9872
[email protected]62e65f02013-05-29 22:28:109873 scoped_refptr<TextureRef> texture_ref =
9874 GetTextureInfoForTargetUnlessDefault(target);
[email protected]370eaf12013-05-18 09:19:499875 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519876 LOCAL_SET_GL_ERROR(
9877 GL_INVALID_OPERATION,
9878 "glConsumeTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599879 return;
9880 }
[email protected]62e65f02013-05-29 22:28:109881 GLuint client_id = texture_ref->client_id();
9882 if (!client_id) {
9883 LOCAL_SET_GL_ERROR(
9884 GL_INVALID_OPERATION,
9885 "glConsumeTextureCHROMIUM", "unknown texture for target");
9886 return;
9887 }
9888 Texture* texture =
[email protected]78b514b2012-05-01 21:50:599889 group_->mailbox_manager()->ConsumeTexture(
9890 target,
[email protected]62e65f02013-05-29 22:28:109891 *reinterpret_cast<const MailboxName*>(mailbox));
9892 if (!texture) {
[email protected]ab09b612013-03-11 22:11:519893 LOCAL_SET_GL_ERROR(
9894 GL_INVALID_OPERATION,
9895 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599896 return;
9897 }
[email protected]62e65f02013-05-29 22:28:109898 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:519899 LOCAL_SET_GL_ERROR(
9900 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:109901 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:599902 return;
9903 }
[email protected]62e65f02013-05-29 22:28:109904
9905 DeleteTexturesHelper(1, &client_id);
9906 texture_ref = texture_manager()->Consume(client_id, texture);
9907 glBindTexture(target, texture_ref->service_id());
9908
9909 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
9910 unit.bind_target = target;
9911 switch (target) {
9912 case GL_TEXTURE_2D:
9913 unit.bound_texture_2d = texture_ref;
9914 break;
9915 case GL_TEXTURE_CUBE_MAP:
9916 unit.bound_texture_cube_map = texture_ref;
9917 break;
9918 case GL_TEXTURE_EXTERNAL_OES:
9919 unit.bound_texture_external_oes = texture_ref;
9920 break;
9921 case GL_TEXTURE_RECTANGLE_ARB:
9922 unit.bound_texture_rectangle_arb = texture_ref;
9923 break;
9924 default:
9925 NOTREACHED(); // Validation should prevent us getting here.
9926 break;
9927 }
[email protected]78b514b2012-05-01 21:50:599928}
9929
[email protected]d2a0e1a2012-08-12 02:25:019930void GLES2DecoderImpl::DoInsertEventMarkerEXT(
9931 GLsizei length, const GLchar* marker) {
9932 if (!marker) {
9933 marker = "";
9934 }
9935 debug_marker_manager_.SetMarker(
9936 length ? std::string(marker, length) : std::string(marker));
9937}
9938
9939void GLES2DecoderImpl::DoPushGroupMarkerEXT(
9940 GLsizei length, const GLchar* marker) {
9941 if (!marker) {
9942 marker = "";
9943 }
9944 debug_marker_manager_.PushGroup(
9945 length ? std::string(marker, length) : std::string(marker));
9946}
9947
9948void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
9949 debug_marker_manager_.PopGroup();
9950}
9951
[email protected]09d50362012-10-18 20:54:379952void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
9953 GLenum target, GLint image_id) {
9954 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
9955 if (target != GL_TEXTURE_2D) {
9956 // This might be supported in the future.
[email protected]ab09b612013-03-11 22:11:519957 LOCAL_SET_GL_ERROR(
[email protected]09d50362012-10-18 20:54:379958 GL_INVALID_OPERATION,
9959 "glBindTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9960 return;
9961 }
9962
9963 // Default target might be conceptually valid, but disallow it to avoid
9964 // accidents.
[email protected]370eaf12013-05-18 09:19:499965 TextureRef* texture_ref = GetTextureInfoForTargetUnlessDefault(target);
9966 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519967 LOCAL_SET_GL_ERROR(
9968 GL_INVALID_OPERATION,
9969 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:379970 return;
9971 }
9972
9973 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
9974 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:519975 LOCAL_SET_GL_ERROR(
9976 GL_INVALID_OPERATION,
9977 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:379978 return;
9979 }
9980
[email protected]b8160812013-04-09 00:41:049981 {
9982 ScopedGLErrorSuppressor suppressor(
9983 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", this);
9984 if (!gl_image->BindTexImage()) {
9985 LOCAL_SET_GL_ERROR(
9986 GL_INVALID_OPERATION,
9987 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
9988 return;
9989 }
[email protected]09d50362012-10-18 20:54:379990 }
9991
9992 gfx::Size size = gl_image->GetSize();
9993 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499994 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:379995 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:499996 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:379997}
9998
9999void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10000 GLenum target, GLint image_id) {
10001 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
10002 if (target != GL_TEXTURE_2D) {
10003 // This might be supported in the future.
[email protected]ab09b612013-03-11 22:11:5110004 LOCAL_SET_GL_ERROR(
[email protected]09d50362012-10-18 20:54:3710005 GL_INVALID_OPERATION,
10006 "glReleaseTexImage2DCHROMIUM", "requires TEXTURE_2D target");
10007 return;
10008 }
10009
10010 // Default target might be conceptually valid, but disallow it to avoid
10011 // accidents.
[email protected]370eaf12013-05-18 09:19:4910012 TextureRef* texture_ref = GetTextureInfoForTargetUnlessDefault(target);
10013 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110014 LOCAL_SET_GL_ERROR(
10015 GL_INVALID_OPERATION,
10016 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710017 return;
10018 }
10019
10020 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10021 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110022 LOCAL_SET_GL_ERROR(
10023 GL_INVALID_OPERATION,
10024 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710025 return;
10026 }
10027
10028 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4910029 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3710030 return;
10031
[email protected]b8160812013-04-09 00:41:0410032 {
10033 ScopedGLErrorSuppressor suppressor(
10034 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", this);
10035 gl_image->ReleaseTexImage();
10036 }
[email protected]09d50362012-10-18 20:54:3710037
10038 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910039 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3710040 GL_RGBA, GL_UNSIGNED_BYTE, false);
10041}
[email protected]d2a0e1a2012-08-12 02:25:0110042
[email protected]94307712012-11-16 23:26:1110043error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510044 uint32 immediate_data_size, const cmds::TraceBeginCHROMIUM& c) {
[email protected]94307712012-11-16 23:26:1110045 Bucket* bucket = GetBucket(c.bucket_id);
10046 if (!bucket || bucket->size() == 0) {
10047 return error::kInvalidArguments;
10048 }
10049 std::string command_name;
10050 if (!bucket->GetAsString(&command_name)) {
10051 return error::kInvalidArguments;
10052 }
[email protected]fb97b662013-02-20 23:02:1410053 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
10054 if (!gpu_tracer_->Begin(command_name)) {
[email protected]ab09b612013-03-11 22:11:5110055 LOCAL_SET_GL_ERROR(
10056 GL_INVALID_OPERATION,
10057 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1410058 return error::kNoError;
10059 }
[email protected]94307712012-11-16 23:26:1110060 return error::kNoError;
10061}
10062
10063void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1410064 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5110065 LOCAL_SET_GL_ERROR(
10066 GL_INVALID_OPERATION,
10067 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1110068 return;
10069 }
[email protected]fb97b662013-02-20 23:02:1410070 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
10071 gpu_tracer_->End();
[email protected]94307712012-11-16 23:26:1110072}
10073
[email protected]2f143d482013-03-14 18:04:4910074void GLES2DecoderImpl::DoDrawBuffersEXT(
10075 GLsizei count, const GLenum* bufs) {
10076 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10077 LOCAL_SET_GL_ERROR(
10078 GL_INVALID_VALUE,
10079 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10080 return;
10081 }
10082
10083 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10084 if (framebuffer) {
10085 for (GLsizei i = 0; i < count; ++i) {
10086 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10087 bufs[i] != GL_NONE) {
10088 LOCAL_SET_GL_ERROR(
10089 GL_INVALID_OPERATION,
10090 "glDrawBuffersEXT",
10091 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10092 return;
10093 }
10094 }
10095 glDrawBuffersARB(count, bufs);
10096 framebuffer->SetDrawBuffers(count, bufs);
10097 } else { // backbuffer
10098 if (count > 1 ||
10099 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10100 LOCAL_SET_GL_ERROR(
10101 GL_INVALID_OPERATION,
10102 "glDrawBuffersEXT",
10103 "more than one buffer or bufs not GL_NONE or GL_BACK");
10104 return;
10105 }
10106 GLenum mapped_buf = bufs[0];
10107 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10108 bufs[0] == GL_BACK) {
10109 mapped_buf = GL_COLOR_ATTACHMENT0;
10110 }
10111 glDrawBuffersARB(count, &mapped_buf);
10112 group_->set_draw_buffer(bufs[0]);
10113 }
10114}
10115
[email protected]32145a92012-12-17 09:01:5910116bool GLES2DecoderImpl::ValidateAsyncTransfer(
10117 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4710118 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5910119 GLenum target,
10120 GLint level,
10121 const void * data) {
10122 // We only support async uploads to 2D textures for now.
10123 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110124 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910125 return false;
10126 }
10127 // We only support uploads to level zero for now.
10128 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110129 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910130 return false;
10131 }
10132 // A transfer buffer must be bound, even for asyncTexImage2D.
10133 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110134 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910135 return false;
10136 }
10137 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4710138 if (!texture_ref ||
10139 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5110140 LOCAL_SET_GL_ERROR(
10141 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910142 function_name, "transfer already in progress");
10143 return false;
10144 }
10145 return true;
10146}
10147
[email protected]69023942012-11-30 19:57:1610148error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510149 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610150 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610151 GLenum target = static_cast<GLenum>(c.target);
10152 GLint level = static_cast<GLint>(c.level);
10153 GLint internal_format = static_cast<GLint>(c.internalformat);
10154 GLsizei width = static_cast<GLsizei>(c.width);
10155 GLsizei height = static_cast<GLsizei>(c.height);
10156 GLint border = static_cast<GLint>(c.border);
10157 GLenum format = static_cast<GLenum>(c.format);
10158 GLenum type = static_cast<GLenum>(c.type);
10159 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10160 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10161 uint32 pixels_size;
[email protected]32145a92012-12-17 09:01:5910162
10163 // TODO(epenner): Move this and copies of this memory validation
10164 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1610165 if (!GLES2Util::ComputeImageDataSizes(
10166 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
10167 NULL)) {
10168 return error::kOutOfBounds;
10169 }
10170 const void* pixels = NULL;
10171 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
10172 pixels = GetSharedMemoryAs<const void*>(
10173 pixels_shm_id, pixels_shm_offset, pixels_size);
10174 if (!pixels) {
10175 return error::kOutOfBounds;
10176 }
10177 }
10178
[email protected]32145a92012-12-17 09:01:5910179 // All the normal glTexSubImage2D validation.
10180 if (!ValidateTexImage2D(
10181 "glAsyncTexImage2DCHROMIUM", target, level, internal_format,
10182 width, height, border, format, type, pixels, pixels_size)) {
10183 return error::kNoError;
10184 }
10185
10186 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4910187 TextureRef* texture_ref = GetTextureInfoForTarget(target);
10188 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910189 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710190 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910191 return error::kNoError;
10192
10193 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0710194 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5110195 LOCAL_SET_GL_ERROR(
10196 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910197 "glAsyncTexImage2DCHROMIUM", "already defined");
10198 return error::kNoError;
10199 }
10200
[email protected]7989c9e2013-01-23 06:39:2610201 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5110202 LOCAL_SET_GL_ERROR(
10203 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610204 return error::kNoError;
10205 }
10206
[email protected]32145a92012-12-17 09:01:5910207 // We know the memory/size is safe, so get the real shared memory since
10208 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110209 gpu::Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
[email protected]32145a92012-12-17 09:01:5910210 base::SharedMemory* shared_memory = buffer.shared_memory;
10211 uint32 shm_size = buffer.size;
10212 uint32 shm_data_offset = c.pixels_shm_offset;
10213 uint32 shm_data_size = pixels_size;
10214
[email protected]5b3a8e02013-03-13 05:36:4410215 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3810216 AsyncTexImage2DParams tex_params = {
10217 target, level, static_cast<GLenum>(internal_format),
10218 width, height, border, format, type};
10219 AsyncMemoryParams mem_params = {
10220 shared_memory, shm_size, shm_data_offset, shm_data_size};
[email protected]32145a92012-12-17 09:01:5910221
[email protected]5b3a8e02013-03-13 05:36:4410222 // Set up the async state if needed, and make the texture
10223 // immutable so the async state stays valid. The level info
10224 // is set up lazily when the transfer completes.
[email protected]85a4ac22013-05-31 01:58:4710225 AsyncPixelTransferState* state =
10226 async_pixel_transfer_manager_->CreatePixelTransferState(texture_ref,
10227 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4410228 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5910229
[email protected]85a4ac22013-05-31 01:58:4710230 GetAsyncPixelTransferDelegate()->AsyncTexImage2D(
10231 state,
[email protected]5b3a8e02013-03-13 05:36:4410232 tex_params,
10233 mem_params,
10234 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4910235 // The callback is only invoked if the transfer delegate still
10236 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4410237 // ownership that both of these pointers are valid.
10238 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4910239 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4410240 tex_params));
[email protected]f598f422012-12-07 08:30:0310241 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610242}
10243
10244error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510245 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610246 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610247 GLenum target = static_cast<GLenum>(c.target);
10248 GLint level = static_cast<GLint>(c.level);
10249 GLint xoffset = static_cast<GLint>(c.xoffset);
10250 GLint yoffset = static_cast<GLint>(c.yoffset);
10251 GLsizei width = static_cast<GLsizei>(c.width);
10252 GLsizei height = static_cast<GLsizei>(c.height);
10253 GLenum format = static_cast<GLenum>(c.format);
10254 GLenum type = static_cast<GLenum>(c.type);
[email protected]32145a92012-12-17 09:01:5910255
10256 // TODO(epenner): Move this and copies of this memory validation
10257 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1610258 uint32 data_size;
10259 if (!GLES2Util::ComputeImageDataSizes(
10260 width, height, format, type, state_.unpack_alignment, &data_size,
10261 NULL, NULL)) {
10262 return error::kOutOfBounds;
10263 }
10264 const void* pixels = GetSharedMemoryAs<const void*>(
10265 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5910266
10267 // All the normal glTexSubImage2D validation.
10268 error::Error error = error::kNoError;
10269 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
10270 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
10271 return error;
[email protected]69023942012-11-30 19:57:1610272 }
10273
[email protected]32145a92012-12-17 09:01:5910274 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4910275 TextureRef* texture_ref = GetTextureInfoForTarget(target);
10276 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910277 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710278 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910279 return error::kNoError;
10280
10281 // Guarantee async textures are always 'cleared' as follows:
10282 // - AsyncTexImage2D can not redefine an existing texture
10283 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
10284 // - AsyncTexSubImage2D clears synchronously if not already cleared.
10285 // - Textures become immutable after an async call.
10286 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0710287 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4910288 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
10289 target, level)) {
[email protected]ab09b612013-03-11 22:11:5110290 LOCAL_SET_GL_ERROR(
10291 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2510292 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5910293 return error::kNoError;
10294 }
10295 }
10296
10297 // We know the memory/size is safe, so get the real shared memory since
10298 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110299 gpu::Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
[email protected]32145a92012-12-17 09:01:5910300 base::SharedMemory* shared_memory = buffer.shared_memory;
10301 uint32 shm_size = buffer.size;
10302 uint32 shm_data_offset = c.data_shm_offset;
10303 uint32 shm_data_size = data_size;
10304
[email protected]5b3a8e02013-03-13 05:36:4410305 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0310306 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5910307 width, height, format, type};
[email protected]2a7568a2013-05-09 23:12:0310308 AsyncMemoryParams mem_params = {shared_memory, shm_size,
[email protected]32145a92012-12-17 09:01:5910309 shm_data_offset, shm_data_size};
[email protected]85a4ac22013-05-31 01:58:4710310 AsyncPixelTransferState* state =
10311 async_pixel_transfer_manager_->GetPixelTransferState(texture_ref);
[email protected]370eaf12013-05-18 09:19:4910312 if (!state) {
[email protected]5b3a8e02013-03-13 05:36:4410313 // TODO(epenner): We may want to enforce exclusive use
10314 // of async APIs in which case this should become an error,
10315 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0310316 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4410317 0, 0, 0, 0, 0, 0};
10318 texture->GetLevelSize(target, level, &define_params.width,
10319 &define_params.height);
10320 texture->GetLevelType(target, level, &define_params.type,
10321 &define_params.internal_format);
10322 // Set up the async state if needed, and make the texture
10323 // immutable so the async state stays valid.
[email protected]85a4ac22013-05-31 01:58:4710324 state = async_pixel_transfer_manager_->CreatePixelTransferState(
10325 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4410326 texture->SetImmutable(true);
10327 }
10328
[email protected]85a4ac22013-05-31 01:58:4710329 GetAsyncPixelTransferDelegate()->AsyncTexSubImage2D(
[email protected]370eaf12013-05-18 09:19:4910330 state, tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5910331 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610332}
10333
[email protected]a00c1f742013-03-05 17:02:1610334error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
10335 uint32 immediate_data_size, const cmds::WaitAsyncTexImage2DCHROMIUM& c) {
10336 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10337 GLenum target = static_cast<GLenum>(c.target);
10338
10339 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110340 LOCAL_SET_GL_ERROR(
10341 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1610342 return error::kNoError;
10343 }
[email protected]370eaf12013-05-18 09:19:4910344 TextureRef* texture_ref = GetTextureInfoForTarget(target);
10345 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110346 LOCAL_SET_GL_ERROR(
10347 GL_INVALID_OPERATION,
10348 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1610349 return error::kNoError;
10350 }
[email protected]370eaf12013-05-18 09:19:4910351 AsyncPixelTransferState* state =
[email protected]85a4ac22013-05-31 01:58:4710352 async_pixel_transfer_manager_->GetPixelTransferState(texture_ref);
[email protected]370eaf12013-05-18 09:19:4910353 if (!state) {
10354 LOCAL_SET_GL_ERROR(
10355 GL_INVALID_OPERATION,
10356 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
10357 return error::kNoError;
10358 }
[email protected]85a4ac22013-05-31 01:58:4710359 GetAsyncPixelTransferDelegate()->WaitForTransferCompletion(state);
[email protected]69a8701e2013-03-07 21:31:0910360 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1610361 return error::kNoError;
10362}
10363
[email protected]96449d2c2009-11-25 00:01:3210364// Include the auto-generated part of this file. We split this because it means
10365// we can easily edit the non-auto generated parts right here in this file
10366// instead of having to edit some template or the code generator.
10367#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
10368
10369} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2510370} // namespace gpu