blob: e3fcd46f5fd9e1de37c12157e4cada886089a76c [file] [log] [blame]
[email protected]529c6672012-01-04 02:18:261// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]96449d2c2009-11-25 00:01:322// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]8a837bb2010-01-05 00:21:245#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
[email protected]74470702010-01-06 18:51:166
7#include <stdio.h>
8
[email protected]1aef98132010-02-23 18:00:079#include <algorithm>
[email protected]f39f4b3f2010-05-12 17:04:0810#include <list>
[email protected]96449d2c2009-11-25 00:01:3211#include <map>
[email protected]94307712012-11-16 23:26:1112#include <stack>
[email protected]f39f4b3f2010-05-12 17:04:0813#include <string>
14#include <vector>
[email protected]5a6db6c2010-04-22 18:32:0615
[email protected]00eb49a2010-08-12 20:46:5716#include "base/at_exit.h"
[email protected]9d37f062011-11-22 01:24:5217#include "base/bind.h"
[email protected]e844ae22012-01-14 03:36:2618#include "base/command_line.h"
[email protected]1078f912011-12-23 13:12:1419#include "base/debug/trace_event.h"
[email protected]3b63f8f42011-03-28 01:54:1520#include "base/memory/scoped_ptr.h"
[email protected]f4390962013-06-11 07:29:2221#include "base/strings/string_number_conversions.h"
[email protected]d37231fa2010-04-09 21:16:0222#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3223#define GLES2_GPU_SERVICE 1
[email protected]f4390962013-06-11 07:29:2224#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]96449d2c2009-11-25 00:01:3225#include "gpu/command_buffer/common/gles2_cmd_format.h"
26#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]066849e32010-05-03 19:14:1027#include "gpu/command_buffer/common/id_allocator.h"
[email protected]2ad674132013-06-05 07:48:5128#include "gpu/command_buffer/common/mailbox.h"
[email protected]f4390962013-06-11 07:29:2229#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
30#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
[email protected]3916c97e2010-02-25 03:20:5031#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3232#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5033#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2434#include "gpu/command_buffer/service/context_state.h"
[email protected]d3eba342013-04-18 21:11:5035#include "gpu/command_buffer/service/error_state.h"
[email protected]915a59a12010-09-30 21:29:1136#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5837#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3238#include "gpu/command_buffer/service/gl_utils.h"
[email protected]43410e92012-04-20 17:06:2839#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4640#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]8f9b8dd2013-09-12 18:05:1341#include "gpu/command_buffer/service/gpu_state_tracer.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]944b62f32012-09-27 02:20:4656#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]f4390962013-06-11 07:29:2257#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]d8bc3ec2013-03-07 06:28:4058#include "ui/gl/gl_bindings.h"
[email protected]5a36dc132013-07-23 23:17:5559#include "ui/gl/gl_fence.h"
[email protected]09d50362012-10-18 20:54:3760#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2761#include "ui/gl/gl_implementation.h"
62#include "ui/gl/gl_surface.h"
[email protected]423e644f2013-06-19 00:48:2763
[email protected]e51bdf32011-11-23 22:21:4664#if defined(OS_MACOSX)
[email protected]423e644f2013-06-19 00:48:2765#include "ui/gl/io_surface_support_mac.h"
[email protected]e51bdf32011-11-23 22:21:4666#endif
[email protected]de17df392010-04-23 21:09:4167
[email protected]6eb775352013-08-27 05:57:1668#if defined(OS_WIN)
69#include "base/win/win_util.h"
70#endif
71
[email protected]693ca512012-11-13 18:09:1372// TODO(zmo): we can't include "City.h" due to type def conflicts.
73extern uint64 CityHash64(const char*, size_t);
74
[email protected]a7a27ace2009-12-12 00:11:2575namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3276namespace gles2 {
77
[email protected]f0d74742011-10-03 16:31:0478namespace {
[email protected]693ca512012-11-13 18:09:1379
[email protected]f0d74742011-10-03 16:31:0480static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]70dc60932013-06-04 03:33:4981static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
[email protected]aff39ac82013-06-08 04:53:1382static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
[email protected]693ca512012-11-13 18:09:1383
[email protected]3d944a82013-02-12 19:09:0284#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]693ca512012-11-13 18:09:1385khronos_uint64_t CityHashForAngle(const char* name, unsigned int len) {
86 return static_cast<khronos_uint64_t>(
87 CityHash64(name, static_cast<size_t>(len)));
88}
[email protected]3d944a82013-02-12 19:09:0289#endif
[email protected]693ca512012-11-13 18:09:1390
[email protected]448e459e2013-06-12 17:00:4191static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
92 GLint rangeMax,
93 GLint precision) {
94 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
95}
96
[email protected]8dc1bf92013-03-12 03:58:2197static void GetShaderPrecisionFormatImpl(GLenum shader_type,
98 GLenum precision_type,
99 GLint *range, GLint *precision) {
100 switch (precision_type) {
101 case GL_LOW_INT:
102 case GL_MEDIUM_INT:
103 case GL_HIGH_INT:
104 // These values are for a 32-bit twos-complement integer format.
105 range[0] = 31;
106 range[1] = 30;
107 *precision = 0;
108 break;
109 case GL_LOW_FLOAT:
110 case GL_MEDIUM_FLOAT:
111 case GL_HIGH_FLOAT:
112 // These values are for an IEEE single-precision floating-point format.
113 range[0] = 127;
114 range[1] = 127;
115 *precision = 23;
116 break;
117 default:
118 NOTREACHED();
119 break;
120 }
121
[email protected]8af4d5e2013-03-15 23:55:33122 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
123 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21124 // This function is sometimes defined even though it's really just
125 // a stub, so we need to set range and precision as if it weren't
126 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44127 // On Mac OS with some GPUs, calling this generates a
128 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
129 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21130 glGetShaderPrecisionFormat(shader_type, precision_type,
131 range, precision);
[email protected]448e459e2013-06-12 17:00:41132
133 // TODO(brianderson): Make the following official workarounds.
134
135 // Some drivers have bugs where they report the ranges as a negative number.
136 // Taking the absolute value here shouldn't hurt because negative numbers
137 // aren't expected anyway.
138 range[0] = abs(range[0]);
139 range[1] = abs(range[1]);
140
141 // If the driver reports a precision for highp float that isn't actually
142 // highp, don't pretend like it's supported because shader compilation will
143 // fail anyway.
144 if (precision_type == GL_HIGH_FLOAT &&
145 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
146 range[0] = 0;
147 range[1] = 0;
148 *precision = 0;
149 }
[email protected]8dc1bf92013-03-12 03:58:21150 }
151}
152
[email protected]b04e24c2013-01-08 18:35:25153} // namespace
[email protected]f0d74742011-10-03 16:31:04154
[email protected]6217d392010-03-25 22:08:35155class GLES2DecoderImpl;
156
[email protected]ab09b612013-03-11 22:11:51157// Local versions of the SET_GL_ERROR macros
158#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50159 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51160#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50161 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
162 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51163#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50164 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
165 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51166#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50167 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
168 function_name)
[email protected]ab09b612013-03-11 22:11:51169#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50170 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51171#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50172 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51173#define LOCAL_PERFORMANCE_WARNING(msg) \
174 PerformanceWarning(__FILE__, __LINE__, msg)
175#define LOCAL_RENDER_WARNING(msg) \
176 RenderWarning(__FILE__, __LINE__, msg)
177
[email protected]07f54fcc2009-12-22 02:46:30178// Check that certain assumptions the code makes are true. There are places in
179// the code where shared memory is passed direclty to GL. Example, glUniformiv,
180// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
181// a few others) are 32bits. If they are not 32bits the code will have to change
182// to call those GL functions with service side memory and then copy the results
183// to shared memory, converting the sizes.
184COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
185 GLint_not_same_size_as_uint32);
186COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
187 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37188COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
189 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30190
[email protected]43f28f832010-02-03 02:28:48191// TODO(kbr): the use of this anonymous namespace core dumps the
192// linker on Mac OS X 10.6 when the symbol ordering file is used
193// namespace {
[email protected]96449d2c2009-11-25 00:01:32194
195// Returns the address of the first byte after a struct.
196template <typename T>
197const void* AddressAfterStruct(const T& pod) {
198 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
199}
200
[email protected]07f54fcc2009-12-22 02:46:30201// Returns the address of the frst byte after the struct or NULL if size >
202// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32203template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30204RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
205 uint32 size,
206 uint32 immediate_data_size) {
207 return (size <= immediate_data_size) ?
208 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
209 NULL;
[email protected]96449d2c2009-11-25 00:01:32210}
211
[email protected]07f54fcc2009-12-22 02:46:30212// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18213bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32214 GLuint count,
215 size_t size,
[email protected]a76b0052010-03-05 00:33:18216 unsigned int elements_per_unit,
217 uint32* dst) {
218 uint32 value;
219 if (!SafeMultiplyUint32(count, size, &value)) {
220 return false;
221 }
222 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
223 return false;
224 }
225 *dst = value;
226 return true;
[email protected]96449d2c2009-11-25 00:01:32227}
228
229// A struct to hold info about each command.
230struct CommandInfo {
231 int arg_flags; // How to handle the arguments for this command
232 int arg_count; // How many arguments are expected for this command.
233};
234
235// A table of CommandInfo for all the commands.
236const CommandInfo g_command_info[] = {
[email protected]ed9f9cd2013-02-27 21:12:35237 #define GLES2_CMD_OP(name) { \
238 cmds::name::kArgFlags, \
239 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \
[email protected]96449d2c2009-11-25 00:01:32240
241 GLES2_COMMAND_LIST(GLES2_CMD_OP)
242
243 #undef GLES2_CMD_OP
244};
245
[email protected]258a3313f2011-10-18 20:13:57246// Return true if a character belongs to the ASCII subset as defined in
247// GLSL ES 1.0 spec section 3.1.
248static bool CharacterIsValidForGLES(unsigned char c) {
249 // Printing characters are valid except " $ ` @ \ ' DEL.
250 if (c >= 32 && c <= 126 &&
251 c != '"' &&
252 c != '$' &&
253 c != '`' &&
254 c != '@' &&
255 c != '\\' &&
256 c != '\'') {
257 return true;
258 }
259 // Horizontal tab, line feed, vertical tab, form feed, carriage return
260 // are also valid.
261 if (c >= 9 && c <= 13) {
262 return true;
263 }
264
265 return false;
266}
267
268static bool StringIsValidForGLES(const char* str) {
269 for (; *str; ++str) {
270 if (!CharacterIsValidForGLES(*str)) {
271 return false;
272 }
273 }
274 return true;
275}
276
[email protected]297ca1c2011-06-20 23:08:46277// Wrapper for glEnable/glDisable that doesn't suck.
278static void EnableDisable(GLenum pname, bool enable) {
279 if (enable) {
280 glEnable(pname);
281 } else {
282 glDisable(pname);
283 }
284}
285
[email protected]6217d392010-03-25 22:08:35286// This class prevents any GL errors that occur when it is in scope from
287// being reported to the client.
288class ScopedGLErrorSuppressor {
289 public:
[email protected]ab09b612013-03-11 22:11:51290 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30291 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35292 ~ScopedGLErrorSuppressor();
293 private:
[email protected]ab09b612013-03-11 22:11:51294 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30295 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35296 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
297};
298
299// Temporarily changes a decoder's bound 2D texture and restore it when this
300// object goes out of scope. Also temporarily switches to using active texture
301// unit zero in case the client has changed that to something invalid.
302class ScopedTexture2DBinder {
303 public:
[email protected]ce296892013-10-24 22:04:36304 ScopedTexture2DBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35305 ~ScopedTexture2DBinder();
306
307 private:
[email protected]ce296892013-10-24 22:04:36308 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35309 DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder);
310};
311
312// Temporarily changes a decoder's bound render buffer and restore it when this
313// object goes out of scope.
314class ScopedRenderBufferBinder {
315 public:
[email protected]18e785a2013-10-09 03:29:41316 ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35317 ~ScopedRenderBufferBinder();
318
319 private:
[email protected]18e785a2013-10-09 03:29:41320 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35321 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
322};
323
324// Temporarily changes a decoder's bound frame buffer and restore it when this
325// object goes out of scope.
326class ScopedFrameBufferBinder {
327 public:
328 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
329 ~ScopedFrameBufferBinder();
330
331 private:
332 GLES2DecoderImpl* decoder_;
333 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
334};
335
[email protected]34ff8b0c2010-10-01 20:06:02336// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52337// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27338// if it is bound or enforce_internal_framebuffer is true. If internal is
339// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02340class ScopedResolvedFrameBufferBinder {
341 public:
[email protected]e7e38032011-07-26 17:25:25342 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
[email protected]de26b3c2011-08-03 21:54:27343 bool enforce_internal_framebuffer,
344 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02345 ~ScopedResolvedFrameBufferBinder();
346
347 private:
348 GLES2DecoderImpl* decoder_;
349 bool resolve_and_bind_;
350 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
351};
352
[email protected]6217d392010-03-25 22:08:35353// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35354class BackTexture {
[email protected]6217d392010-03-25 22:08:35355 public:
[email protected]ce296892013-10-24 22:04:36356 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35357 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35358
359 // Create a new render texture.
360 void Create();
361
362 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09363 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35364
365 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58366 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35367
368 // Destroy the render texture. This must be explicitly called before
369 // destroying this object.
370 void Destroy();
371
[email protected]97872062010-11-03 19:07:05372 // Invalidate the texture. This can be used when a context is lost and it is
373 // not possible to make it current in order to free the resource.
374 void Invalidate();
375
[email protected]6217d392010-03-25 22:08:35376 GLuint id() const {
377 return id_;
378 }
379
[email protected]d37231fa2010-04-09 21:16:02380 gfx::Size size() const {
381 return size_;
382 }
383
[email protected]1078f912011-12-23 13:12:14384 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25385 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14386 }
387
[email protected]6217d392010-03-25 22:08:35388 private:
[email protected]ff6493f2012-07-31 19:52:25389 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36390 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48391 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35392 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02393 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35394 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35395};
396
397// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35398class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35399 public:
[email protected]d5a28e452013-10-10 01:01:40400 explicit BackRenderbuffer(
401 RenderbufferManager* renderbuffer_manager,
402 MemoryTracker* memory_tracker,
403 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35404 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35405
406 // Create a new render buffer.
407 void Create();
408
409 // Set the initial size and format of a render buffer or resize it.
[email protected]34ff8b0c2010-10-01 20:06:02410 bool AllocateStorage(const gfx::Size& size, GLenum format, GLsizei samples);
[email protected]6217d392010-03-25 22:08:35411
412 // Destroy the render buffer. This must be explicitly called before destroying
413 // this object.
414 void Destroy();
415
[email protected]97872062010-11-03 19:07:05416 // Invalidate the render buffer. This can be used when a context is lost and
417 // it is not possible to make it current in order to free the resource.
418 void Invalidate();
419
[email protected]6217d392010-03-25 22:08:35420 GLuint id() const {
421 return id_;
422 }
423
[email protected]1078f912011-12-23 13:12:14424 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25425 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14426 }
427
[email protected]6217d392010-03-25 22:08:35428 private:
[email protected]d5a28e452013-10-10 01:01:40429 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25430 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40431 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48432 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35433 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35434 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35435};
436
437// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35438class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35439 public:
[email protected]ed9f9cd2013-02-27 21:12:35440 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
441 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35442
443 // Create a new frame buffer.
444 void Create();
445
446 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35447 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35448
[email protected]b9363b22010-06-09 22:06:15449 // Attach a render buffer to a frame buffer. Note that this unbinds any
450 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35451 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35452
[email protected]6217d392010-03-25 22:08:35453 // Destroy the frame buffer. This must be explicitly called before destroying
454 // this object.
455 void Destroy();
456
[email protected]97872062010-11-03 19:07:05457 // Invalidate the frame buffer. This can be used when a context is lost and it
458 // is not possible to make it current in order to free the resource.
459 void Invalidate();
460
[email protected]6217d392010-03-25 22:08:35461 // See glCheckFramebufferStatusEXT.
462 GLenum CheckStatus();
463
464 GLuint id() const {
465 return id_;
466 }
467
468 private:
469 GLES2DecoderImpl* decoder_;
470 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35471 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35472};
[email protected]34ff8b0c2010-10-01 20:06:02473
[email protected]5a36dc132013-07-23 23:17:55474struct FenceCallback {
475 explicit FenceCallback()
476 : fence(gfx::GLFence::Create()) {
477 DCHECK(fence);
478 }
479 void AddCallback(base::Closure cb) {
480 callbacks.push_back(cb);
481 }
482 std::vector<base::Closure> callbacks;
483 scoped_ptr<gfx::GLFence> fence;
484};
485
486
[email protected]43f28f832010-02-03 02:28:48487// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32488
[email protected]ddb1e5a2010-12-13 20:10:45489bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
490 uint32* service_texture_id) {
491 return false;
492}
493
[email protected]a3ded6d2010-10-19 06:44:39494GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06495 : initialized_(false),
496 debug_(false),
[email protected]1d82e822013-04-10 21:32:32497 log_commands_(false) {
[email protected]96449d2c2009-11-25 00:01:32498}
499
[email protected]3916c97e2010-02-25 03:20:50500GLES2Decoder::~GLES2Decoder() {
501}
502
[email protected]57edfdad2012-02-07 04:57:15503bool GLES2Decoder::testing_force_is_angle_;
504
505void GLES2Decoder::set_testing_force_is_angle(bool force) {
506 testing_force_is_angle_ = force;
507}
508
509bool GLES2Decoder::IsAngle() {
510#if defined(OS_WIN)
511 return testing_force_is_angle_ ||
512 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2;
513#else
514 return testing_force_is_angle_;
515#endif
516}
517
[email protected]f39f4b3f2010-05-12 17:04:08518// This class implements GLES2Decoder so we don't have to expose all the GLES2
519// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54520class GLES2DecoderImpl : public GLES2Decoder,
521 public FramebufferManager::TextureDetachObserver {
[email protected]f39f4b3f2010-05-12 17:04:08522 public:
[email protected]476ccb72012-12-06 15:52:52523 // Used by PrepForSetUniformByLocation to validate types.
524 struct BaseUniformInfo {
525 const GLenum* const valid_types;
526 size_t num_valid_types;
527 };
528
[email protected]aa7666122011-09-02 19:45:52529 explicit GLES2DecoderImpl(ContextGroup* group);
[email protected]b8e97b62012-09-30 15:09:00530 virtual ~GLES2DecoderImpl();
[email protected]f39f4b3f2010-05-12 17:04:08531
[email protected]96449d2c2009-11-25 00:01:32532 // Overridden from AsyncAPIInterface.
[email protected]f7a64ee2010-02-01 22:24:14533 virtual Error DoCommand(unsigned int command,
[email protected]3916c97e2010-02-25 03:20:50534 unsigned int arg_count,
[email protected]b8e97b62012-09-30 15:09:00535 const void* args) OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32536
537 // Overridden from AsyncAPIInterface.
[email protected]b8e97b62012-09-30 15:09:00538 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32539
540 // Overridden from GLES2Decoder.
[email protected]fbe20372011-06-01 01:46:38541 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
542 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:23543 bool offscreen,
[email protected]6217d392010-03-25 22:08:35544 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29545 const DisallowedFeatures& disallowed_features,
[email protected]b8e97b62012-09-30 15:09:00546 const std::vector<int32>& attribs) OVERRIDE;
547 virtual void Destroy(bool have_context) OVERRIDE;
[email protected]63c9b052012-05-17 18:27:38548 virtual void SetSurface(
549 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
[email protected]2ad674132013-06-05 07:48:51550 virtual bool ProduceFrontBuffer(const Mailbox& mailbox) OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00551 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
[email protected]9a5afa432011-07-22 18:16:39552 void UpdateParentTextureInfo();
[email protected]b8e97b62012-09-30 15:09:00553 virtual bool MakeCurrent() OVERRIDE;
554 virtual void ReleaseCurrent() OVERRIDE;
555 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
556 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
557 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
[email protected]1868a342012-11-07 15:56:02558 virtual void RestoreState() const OVERRIDE;
[email protected]29a4d902013-02-26 20:18:06559
560 virtual void RestoreActiveTexture() const OVERRIDE {
561 state_.RestoreActiveTexture();
562 }
[email protected]217004512013-05-10 21:25:55563 virtual void RestoreAllTextureUnitBindings() const OVERRIDE {
564 state_.RestoreAllTextureUnitBindings();
565 }
[email protected]29a4d902013-02-26 20:18:06566 virtual void RestoreAttribute(unsigned index) const OVERRIDE {
567 state_.RestoreAttribute(index);
568 }
569 virtual void RestoreBufferBindings() const OVERRIDE {
570 state_.RestoreBufferBindings();
571 }
572 virtual void RestoreGlobalState() const OVERRIDE {
573 state_.RestoreGlobalState();
574 }
575 virtual void RestoreProgramBindings() const OVERRIDE {
576 state_.RestoreProgramBindings();
577 }
578 virtual void RestoreRenderbufferBindings() const OVERRIDE {
579 state_.RestoreRenderbufferBindings();
580 }
581 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE {
582 state_.RestoreTextureUnitBindings(unit);
583 }
584 virtual void RestoreFramebufferBindings() const OVERRIDE;
585 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE;
586
[email protected]b8e97b62012-09-30 15:09:00587 virtual QueryManager* GetQueryManager() OVERRIDE {
588 return query_manager_.get();
589 }
590 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
[email protected]944b62f32012-09-27 02:20:46591 return vertex_array_manager_.get();
592 }
[email protected]b8e97b62012-09-30 15:09:00593 virtual bool ProcessPendingQueries() OVERRIDE;
[email protected]2b1767cf2013-03-16 09:25:05594 virtual bool HasMoreIdleWork() OVERRIDE;
595 virtual void PerformIdleWork() OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48596
[email protected]5a36dc132013-07-23 23:17:55597 virtual void WaitForReadPixels(base::Closure callback) OVERRIDE;
598
[email protected]9d37f062011-11-22 01:24:52599 virtual void SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:07600 const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00601
[email protected]1d82e822013-04-10 21:32:32602 virtual Logger* GetLogger() OVERRIDE;
[email protected]d3eba342013-04-18 21:11:50603 virtual ErrorState* GetErrorState() OVERRIDE;
[email protected]1d82e822013-04-10 21:32:32604
[email protected]e3932abb2013-03-13 00:01:37605 virtual void SetShaderCacheCallback(
606 const ShaderCacheCallback& callback) OVERRIDE;
[email protected]840a7e462013-02-27 01:29:51607 virtual void SetWaitSyncPointCallback(
608 const WaitSyncPointCallback& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00609
[email protected]85a4ac22013-05-31 01:58:47610 virtual AsyncPixelTransferManager*
611 GetAsyncPixelTransferManager() OVERRIDE;
612 virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE;
[email protected]498b5c072013-06-04 19:30:07613 virtual void SetAsyncPixelTransferManagerForTest(
614 AsyncPixelTransferManager* manager) OVERRIDE;
[email protected]69a8701e2013-03-07 21:31:09615 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59616
[email protected]1318e922010-09-17 22:03:16617 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00618 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48619
[email protected]63b465922012-09-06 02:04:52620 virtual uint32 GetTextureUploadCount() OVERRIDE;
621 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
622 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30623 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52624
[email protected]8e3e0662010-08-23 18:46:30625 // Restores the current state to the user's settings.
626 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30627
[email protected]297ca1c2011-06-20 23:08:46628 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
629 void ApplyDirtyState();
630
631 // These check the state of the currently bound framebuffer or the
632 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54633 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
634 // check with all attached and enabled color attachments.
635 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46636 bool BoundFramebufferHasDepthAttachment();
637 bool BoundFramebufferHasStencilAttachment();
638
[email protected]b8e97b62012-09-30 15:09:00639 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43640
[email protected]91c94eb2013-10-22 10:32:54641 // Overridden from FramebufferManager::TextureDetachObserver:
642 virtual void OnTextureRefDetachedFromFramebuffer(
643 TextureRef* texture) OVERRIDE;
644
[email protected]96449d2c2009-11-25 00:01:32645 private:
[email protected]70d34263c2013-01-09 00:27:45646 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02647 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35648 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35649
[email protected]c2f8c8402010-12-06 18:07:24650 // Initialize or re-initialize the shader translator.
651 bool InitializeShaderTranslator();
652
[email protected]302ce6d2011-07-07 23:28:11653 void UpdateCapabilities();
654
[email protected]ae51d192010-04-27 00:48:03655 // Helpers for the glGen and glDelete functions.
656 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
657 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
658 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
659 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
660 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
661 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
662 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
663 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53664 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
665 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46666 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
667 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47668
[email protected]70d34263c2013-01-09 00:27:45669 // Workarounds
670 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51671 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45672
[email protected]3916c97e2010-02-25 03:20:50673 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50674 BufferManager* buffer_manager() {
675 return group_->buffer_manager();
676 }
677
[email protected]a25fa872010-03-25 02:57:58678 RenderbufferManager* renderbuffer_manager() {
679 return group_->renderbuffer_manager();
680 }
681
682 FramebufferManager* framebuffer_manager() {
683 return group_->framebuffer_manager();
684 }
685
[email protected]3916c97e2010-02-25 03:20:50686 ProgramManager* program_manager() {
687 return group_->program_manager();
688 }
689
690 ShaderManager* shader_manager() {
691 return group_->shader_manager();
692 }
693
[email protected]29a4d902013-02-26 20:18:06694 const TextureManager* texture_manager() const {
695 return group_->texture_manager();
696 }
697
[email protected]3916c97e2010-02-25 03:20:50698 TextureManager* texture_manager() {
699 return group_->texture_manager();
700 }
701
[email protected]78b514b2012-05-01 21:50:59702 MailboxManager* mailbox_manager() {
703 return group_->mailbox_manager();
704 }
705
[email protected]09d50362012-10-18 20:54:37706 ImageManager* image_manager() {
707 return group_->image_manager();
708 }
709
[email protected]944b62f32012-09-27 02:20:46710 VertexArrayManager* vertex_array_manager() {
711 return vertex_array_manager_.get();
712 }
713
[email protected]7989c9e2013-01-23 06:39:26714 MemoryTracker* memory_tracker() {
715 return group_->memory_tracker();
716 }
717
[email protected]4f9958142013-07-02 03:58:07718 StreamTextureManager* stream_texture_manager() const {
719 return group_->stream_texture_manager();
720 }
721
[email protected]7989c9e2013-01-23 06:39:26722 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
723 MemoryTracker* tracker = memory_tracker();
724 if (tracker) {
725 return tracker->EnsureGPUMemoryAvailable(estimated_size);
726 }
727 return true;
728 }
729
[email protected]34ff8b0c2010-10-01 20:06:02730 bool IsOffscreenBufferMultisampled() const {
731 return offscreen_target_samples_ > 1;
732 }
733
[email protected]ed9f9cd2013-02-27 21:12:35734 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49735 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03736 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35737 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47738 }
739
740 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49741 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07742 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47743 }
744
745 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35746 void RemoveTexture(GLuint client_id) {
747 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50748 }
[email protected]a93bb842010-02-16 23:03:47749
[email protected]d37231fa2010-04-09 21:16:02750 // Get the size (in pixels) of the currently bound frame buffer (either FBO
751 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30752 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02753
[email protected]9edc6b22010-12-23 02:00:26754 // Get the format of the currently bound frame buffer (either FBO or regular
755 // back buffer)
756 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46757 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26758
[email protected]a93bb842010-02-16 23:03:47759 // Wrapper for CompressedTexImage2D commands.
760 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37761 GLenum target,
762 GLint level,
763 GLenum internal_format,
764 GLsizei width,
765 GLsizei height,
766 GLint border,
767 GLsizei image_size,
768 const void* data);
[email protected]a93bb842010-02-16 23:03:47769
[email protected]cadde4a2010-07-31 17:10:43770 // Wrapper for CompressedTexSubImage2D.
771 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37772 GLenum target,
773 GLint level,
774 GLint xoffset,
775 GLint yoffset,
776 GLsizei width,
777 GLsizei height,
778 GLenum format,
779 GLsizei imageSize,
780 const void * data);
[email protected]cadde4a2010-07-31 17:10:43781
782 // Wrapper for CopyTexImage2D.
783 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37784 GLenum target,
785 GLint level,
786 GLenum internal_format,
787 GLint x,
788 GLint y,
789 GLsizei width,
790 GLsizei height,
791 GLint border);
[email protected]cadde4a2010-07-31 17:10:43792
[email protected]6d792ee12013-05-15 00:40:56793 // Wrapper for SwapBuffers.
794 void DoSwapBuffers();
795
[email protected]cadde4a2010-07-31 17:10:43796 // Wrapper for CopyTexSubImage2D.
797 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37798 GLenum target,
799 GLint level,
800 GLint xoffset,
801 GLint yoffset,
802 GLint x,
803 GLint y,
804 GLsizei width,
805 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43806
[email protected]f598f422012-12-07 08:30:03807 // Validation for TexSubImage2D.
808 bool ValidateTexSubImage2D(
809 error::Error* error,
810 const char* function_name,
811 GLenum target,
812 GLint level,
813 GLint xoffset,
814 GLint yoffset,
815 GLsizei width,
816 GLsizei height,
817 GLenum format,
818 GLenum type,
819 const void * data);
820
[email protected]cadde4a2010-07-31 17:10:43821 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03822 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37823 GLenum target,
824 GLint level,
825 GLint xoffset,
826 GLint yoffset,
827 GLsizei width,
828 GLsizei height,
829 GLenum format,
830 GLenum type,
831 const void * data);
[email protected]cadde4a2010-07-31 17:10:43832
[email protected]32145a92012-12-17 09:01:59833 // Extra validation for async tex(Sub)Image2D.
834 bool ValidateAsyncTransfer(
835 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47836 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59837 GLenum target,
838 GLint level,
839 const void * data);
840
[email protected]e51bdf32011-11-23 22:21:46841 // Wrapper for TexImageIOSurface2DCHROMIUM.
842 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37843 GLenum target,
844 GLsizei width,
845 GLsizei height,
846 GLuint io_surface_id,
847 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46848
[email protected]43410e92012-04-20 17:06:28849 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37850 GLenum target,
851 GLuint source_id,
852 GLuint target_id,
853 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54854 GLenum internal_format,
855 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28856
[email protected]97dc7cbe2011-12-06 17:26:17857 // Wrapper for TexStorage2DEXT.
858 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37859 GLenum target,
860 GLint levels,
861 GLenum internal_format,
862 GLsizei width,
863 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17864
[email protected]78b514b2012-05-01 21:50:59865 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
866 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
867
[email protected]09d50362012-10-18 20:54:37868 void DoBindTexImage2DCHROMIUM(
869 GLenum target,
870 GLint image_id);
871 void DoReleaseTexImage2DCHROMIUM(
872 GLenum target,
873 GLint image_id);
874
[email protected]94307712012-11-16 23:26:11875 void DoTraceEndCHROMIUM(void);
876
[email protected]2f143d482013-03-14 18:04:49877 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
878
[email protected]ed9f9cd2013-02-27 21:12:35879 // Creates a Program for the given program.
880 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57881 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35882 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47883 }
884
[email protected]07f54fcc2009-12-22 02:46:30885 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35886 Program* GetProgram(GLuint client_id) {
887 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46888 }
[email protected]07f54fcc2009-12-22 02:46:30889
[email protected]cae20172012-12-07 00:06:19890#if defined(NDEBUG)
891 void LogClientServiceMapping(
892 const char* /* function_name */,
893 GLuint /* client_id */,
894 GLuint /* service_id */) {
895 }
896 template<typename T>
897 void LogClientServiceForInfo(
898 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
899 }
900#else
901 void LogClientServiceMapping(
902 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:26903 if (service_logging_) {
[email protected]1d82e822013-04-10 21:32:32904 DLOG(INFO) << "[" << logger_.GetLogPrefix() << "] " << function_name
[email protected]2a22fe72012-12-07 04:21:26905 << ": client_id = " << client_id
906 << ", service_id = " << service_id;
907 }
[email protected]cae20172012-12-07 00:06:19908 }
909 template<typename T>
910 void LogClientServiceForInfo(
911 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:26912 if (info) {
[email protected]cae20172012-12-07 00:06:19913 LogClientServiceMapping(function_name, client_id, info->service_id());
914 }
915 }
916#endif
917
[email protected]6b8cf1a2010-05-06 16:13:58918 // Gets the program info for the given program. If it's not a program
919 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:35920 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:58921 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42922 Program* program = GetProgram(client_id);
923 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:35924 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:51925 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43926 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:58927 } else {
[email protected]ab09b612013-03-11 22:11:51928 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:58929 }
930 }
[email protected]df37b9932013-03-08 05:21:42931 LogClientServiceForInfo(program, client_id, function_name);
932 return program;
[email protected]6b8cf1a2010-05-06 16:13:58933 }
934
935
[email protected]ed9f9cd2013-02-27 21:12:35936 // Creates a Shader for the given shader.
937 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:57938 GLuint client_id,
939 GLuint service_id,
940 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:35941 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:57942 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:31943 }
944
945 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35946 Shader* GetShader(GLuint client_id) {
947 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:31948 }
949
[email protected]6b8cf1a2010-05-06 16:13:58950 // Gets the shader info for the given shader. If it's not a shader generates a
951 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:35952 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:58953 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42954 Shader* shader = GetShader(client_id);
955 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:35956 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:51957 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43958 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:58959 } else {
[email protected]ab09b612013-03-11 22:11:51960 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43961 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:58962 }
963 }
[email protected]df37b9932013-03-08 05:21:42964 LogClientServiceForInfo(shader, client_id, function_name);
965 return shader;
[email protected]6b8cf1a2010-05-06 16:13:58966 }
967
[email protected]a93bb842010-02-16 23:03:47968 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:35969 void CreateBuffer(GLuint client_id, GLuint service_id) {
970 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47971 }
972
[email protected]07f54fcc2009-12-22 02:46:30973 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:21974 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:07975 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
976 return buffer;
[email protected]1d32bc82010-01-13 22:06:46977 }
[email protected]07f54fcc2009-12-22 02:46:30978
[email protected]a93bb842010-02-16 23:03:47979 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
980 // on glDeleteBuffers so we can make sure the user does not try to render
981 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:35982 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:47983
[email protected]a25fa872010-03-25 02:57:58984 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:35985 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
986 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:58987 }
988
989 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:06990 Framebuffer* GetFramebuffer(GLuint client_id) {
991 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:58992 }
993
994 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:35995 void RemoveFramebuffer(GLuint client_id) {
996 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:58997 }
998
999 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351000 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1001 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031002 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581003 }
1004
1005 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271006 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1007 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581008 }
1009
1010 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351011 void RemoveRenderbuffer(GLuint client_id) {
1012 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581013 }
1014
[email protected]944b62f32012-09-27 02:20:461015 // Gets the vertex attrib manager for the given vertex array.
1016 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1017 VertexAttribManager* info =
1018 vertex_array_manager()->GetVertexAttribManager(client_id);
1019 return info;
1020 }
1021
1022 // Removes the vertex attrib manager for the given vertex array.
1023 void RemoveVertexAttribManager(GLuint client_id) {
1024 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1025 }
1026
1027 // Creates a vertex attrib manager for the given vertex array.
1028 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) {
1029 return vertex_array_manager()->CreateVertexAttribManager(
1030 client_id, service_id, group_->max_vertex_attribs());
1031 }
1032
[email protected]258a3313f2011-10-18 20:13:571033 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331034 void DoBindUniformLocationCHROMIUM(
1035 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571036
[email protected]558847a2010-03-24 07:02:541037 error::Error GetAttribLocationHelper(
1038 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1039 const std::string& name_str);
1040
1041 error::Error GetUniformLocationHelper(
1042 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1043 const std::string& name_str);
1044
[email protected]3916c97e2010-02-25 03:20:501045 // Helper for glShaderSource.
1046 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031047 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301048
[email protected]0d6bfdc2011-11-02 01:32:201049 // Clear any textures used by the current program.
1050 bool ClearUnclearedTextures();
1051
1052 // Clear any uncleared level in texture.
1053 // Returns false if there was a generated GL error.
[email protected]02965c22013-03-09 02:40:071054 bool ClearTexture(Texture* texture);
[email protected]0d6bfdc2011-11-02 01:32:201055
1056 // Clears any uncleared attachments attached to the given frame buffer.
1057 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061058 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281059
[email protected]0d6bfdc2011-11-02 01:32:201060 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:001061 virtual bool ClearLevel(unsigned service_id,
1062 unsigned bind_target,
1063 unsigned target,
1064 int level,
1065 unsigned format,
1066 unsigned type,
1067 int width,
1068 int height,
1069 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:201070
[email protected]c007aa02010-09-02 22:22:401071 // Restore all GL state that affects clearing.
1072 void RestoreClearState();
1073
[email protected]3a2e7c7b2010-08-06 01:12:281074 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461075 // Returns: true if glEnable/glDisable should actually be called.
1076 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281077
[email protected]0d6bfdc2011-11-02 01:32:201078 // Check that the currently bound framebuffers are valid.
1079 // Generates GL error if not.
1080 bool CheckBoundFramebuffersValid(const char* func_name);
1081
1082 // Check if a framebuffer meets our requirements.
1083 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351084 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201085 GLenum target,
1086 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271087
[email protected]939e7362010-05-13 20:49:101088 // Checks if the current program exists and is valid. If not generates the
1089 // appropriate GL error. Returns true if the current program is in a usable
1090 // state.
1091 bool CheckCurrentProgram(const char* function_name);
1092
1093 // Checks if the current program exists and is valid and that location is not
1094 // -1. If the current program is not valid generates the appropriate GL
1095 // error. Returns true if the current program is in a usable state and
1096 // location is not -1.
1097 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1098
1099 // Gets the type of a uniform for a location in the current program. Sets GL
1100 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361101 // program is valid and the location exists. Adjusts count so it
1102 // does not overflow the uniform.
1103 bool PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:121104 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:521105 const BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:121106 GLint* real_location, GLenum* type, GLsizei* count);
[email protected]939e7362010-05-13 20:49:101107
[email protected]b177ae22011-11-01 03:29:111108 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021109 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111110
[email protected]b273e432010-04-12 17:23:581111 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1112 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1113
[email protected]ac77603c72013-03-08 13:52:061114 // Helper for glGetVertexAttrib
1115 void GetVertexAttribHelper(
1116 const VertexAttrib* attrib, GLenum pname, GLint* param);
1117
[email protected]96449d2c2009-11-25 00:01:321118 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031119 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321120
1121 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031122 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321123
[email protected]3916c97e2010-02-25 03:20:501124 // Wrapper for glActiveTexture
1125 void DoActiveTexture(GLenum texture_unit);
1126
[email protected]ae51d192010-04-27 00:48:031127 // Wrapper for glAttachShader
1128 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1129
[email protected]96449d2c2009-11-25 00:01:321130 // Wrapper for glBindBuffer since we need to track the current targets.
1131 void DoBindBuffer(GLenum target, GLuint buffer);
1132
[email protected]86093972010-03-11 00:13:561133 // Wrapper for glBindFramebuffer since we need to track the current targets.
1134 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1135
1136 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1137 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1138
[email protected]a93bb842010-02-16 23:03:471139 // Wrapper for glBindTexture since we need to track the current targets.
1140 void DoBindTexture(GLenum target, GLuint texture);
1141
[email protected]944b62f32012-09-27 02:20:461142 // Wrapper for glBindVertexArrayOES
1143 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571144 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461145
[email protected]8e3e0662010-08-23 18:46:301146 // Wrapper for glBlitFramebufferEXT.
1147 void DoBlitFramebufferEXT(
1148 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1149 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1150 GLbitfield mask, GLenum filter);
1151
[email protected]36cef8ce2010-03-16 07:34:451152 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111153 void DoBufferSubData(
1154 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1155
[email protected]36cef8ce2010-03-16 07:34:451156 // Wrapper for glCheckFramebufferStatus
1157 GLenum DoCheckFramebufferStatus(GLenum target);
1158
[email protected]3a03a8f2011-03-19 00:51:271159 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081160 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271161
[email protected]88a61bf2012-10-27 13:00:421162 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421163 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251164 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281165
[email protected]45bf5152010-02-12 00:11:311166 // Wrapper for glCompileShader.
1167 void DoCompileShader(GLuint shader);
1168
[email protected]269200b12010-11-18 22:53:061169 // Helper for DeleteSharedIdsCHROMIUM commands.
1170 void DoDeleteSharedIdsCHROMIUM(
1171 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101172
[email protected]ae51d192010-04-27 00:48:031173 // Wrapper for glDetachShader
1174 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1175
[email protected]3a2e7c7b2010-08-06 01:12:281176 // Wrapper for glDisable
1177 void DoDisable(GLenum cap);
1178
[email protected]07f54fcc2009-12-22 02:46:301179 // Wrapper for glDisableVertexAttribArray.
1180 void DoDisableVertexAttribArray(GLuint index);
1181
[email protected]60f22d32012-12-12 00:31:581182 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1183 // attachments.
1184 void DoDiscardFramebufferEXT(GLenum target,
1185 GLsizei numAttachments,
1186 const GLenum* attachments);
1187
[email protected]3a2e7c7b2010-08-06 01:12:281188 // Wrapper for glEnable
1189 void DoEnable(GLenum cap);
1190
[email protected]07f54fcc2009-12-22 02:46:301191 // Wrapper for glEnableVertexAttribArray.
1192 void DoEnableVertexAttribArray(GLuint index);
1193
[email protected]882ba1e22012-03-08 19:02:531194 // Wrapper for glFinish.
1195 void DoFinish();
1196
1197 // Wrapper for glFlush.
1198 void DoFlush();
1199
[email protected]36cef8ce2010-03-16 07:34:451200 // Wrapper for glFramebufferRenderbufffer.
1201 void DoFramebufferRenderbuffer(
1202 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1203 GLuint renderbuffer);
1204
1205 // Wrapper for glFramebufferTexture2D.
1206 void DoFramebufferTexture2D(
1207 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1208 GLint level);
1209
[email protected]7d3c36e2013-07-12 14:13:161210 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1211 void DoFramebufferTexture2DMultisample(
1212 GLenum target, GLenum attachment, GLenum textarget,
1213 GLuint texture, GLint level, GLsizei samples);
1214
1215 // Common implementation for both DoFramebufferTexture2D wrappers.
1216 void DoFramebufferTexture2DCommon(const char* name,
1217 GLenum target, GLenum attachment, GLenum textarget,
1218 GLuint texture, GLint level, GLsizei samples);
1219
[email protected]a93bb842010-02-16 23:03:471220 // Wrapper for glGenerateMipmap
1221 void DoGenerateMipmap(GLenum target);
1222
[email protected]269200b12010-11-18 22:53:061223 // Helper for GenSharedIdsCHROMIUM commands.
1224 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101225 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1226
[email protected]7d3c36e2013-07-12 14:13:161227 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1228 // to account for different pname values defined in different extension
1229 // variants.
1230 GLenum AdjustGetPname(GLenum pname);
1231
[email protected]b273e432010-04-12 17:23:581232 // Wrapper for DoGetBooleanv.
1233 void DoGetBooleanv(GLenum pname, GLboolean* params);
1234
1235 // Wrapper for DoGetFloatv.
1236 void DoGetFloatv(GLenum pname, GLfloat* params);
1237
[email protected]36cef8ce2010-03-16 07:34:451238 // Wrapper for glGetFramebufferAttachmentParameteriv.
1239 void DoGetFramebufferAttachmentParameteriv(
1240 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1241
[email protected]a0c3e972010-04-21 00:49:131242 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581243 void DoGetIntegerv(GLenum pname, GLint* params);
1244
[email protected]29a9eb52010-04-13 09:04:231245 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061246 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231247 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1248
[email protected]17cfbe0e2013-03-07 01:26:081249 // Wrapper for glGetBufferParameteriv.
1250 void DoGetBufferParameteriv(
1251 GLenum target, GLenum pname, GLint* params);
1252
[email protected]a0c3e972010-04-21 00:49:131253 // Wrapper for glGetProgramiv.
1254 void DoGetProgramiv(
1255 GLuint program_id, GLenum pname, GLint* params);
1256
[email protected]36cef8ce2010-03-16 07:34:451257 // Wrapper for glRenderbufferParameteriv.
1258 void DoGetRenderbufferParameteriv(
1259 GLenum target, GLenum pname, GLint* params);
1260
[email protected]ddd968b82010-03-02 00:44:291261 // Wrapper for glGetShaderiv
1262 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1263
[email protected]b1122982010-05-17 23:04:241264 // Wrappers for glGetVertexAttrib.
1265 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1266 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1267
[email protected]1958e0e2010-04-22 05:17:151268 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241269 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151270 bool DoIsBuffer(GLuint client_id);
1271 bool DoIsFramebuffer(GLuint client_id);
1272 bool DoIsProgram(GLuint client_id);
1273 bool DoIsRenderbuffer(GLuint client_id);
1274 bool DoIsShader(GLuint client_id);
1275 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461276 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151277
[email protected]07f54fcc2009-12-22 02:46:301278 // Wrapper for glLinkProgram
1279 void DoLinkProgram(GLuint program);
1280
[email protected]269200b12010-11-18 22:53:061281 // Helper for RegisterSharedIdsCHROMIUM.
1282 void DoRegisterSharedIdsCHROMIUM(
1283 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101284
[email protected]36cef8ce2010-03-16 07:34:451285 // Wrapper for glRenderbufferStorage.
1286 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031287 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451288
[email protected]8e3e0662010-08-23 18:46:301289 // Wrapper for glRenderbufferStorageMultisampleEXT.
1290 void DoRenderbufferStorageMultisample(
1291 GLenum target, GLsizei samples, GLenum internalformat,
1292 GLsizei width, GLsizei height);
1293
[email protected]4a4c18b2013-09-13 22:50:101294 // Verifies that the currently bound multisample renderbuffer is valid
1295 // Very slow! Only done on platforms with driver bugs that return invalid
1296 // buffers under memory pressure
1297 bool VerifyMultisampleRenderbufferIntegrity(
1298 GLuint renderbuffer, GLenum format);
1299
[email protected]b273e432010-04-12 17:23:581300 // Wrapper for glReleaseShaderCompiler.
1301 void DoReleaseShaderCompiler() { }
1302
[email protected]3916c97e2010-02-25 03:20:501303 // Wrappers for glTexParameter functions.
1304 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1305 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1306 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1307 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1308
1309 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1310 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121311 void DoUniform1i(GLint fake_location, GLint v0);
1312 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1313 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1314 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1315 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101316
1317 // Wrappers for glUniformfv because some drivers don't correctly accept
1318 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121319 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1320 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1321 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1322 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501323
[email protected]43c2f1f2011-03-25 18:35:361324 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121325 GLint fake_location, GLsizei count, GLboolean transpose,
1326 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361327 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121328 GLint fake_location, GLsizei count, GLboolean transpose,
1329 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361330 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121331 GLint fake_location, GLsizei count, GLboolean transpose,
1332 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361333
[email protected]af6380962012-11-29 23:24:131334 bool SetVertexAttribValue(
1335 const char* function_name, GLuint index, const GLfloat* value);
1336
[email protected]b1122982010-05-17 23:04:241337 // Wrappers for glVertexAttrib??
1338 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1339 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1340 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1341 void DoVertexAttrib4f(
1342 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1343 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1344 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1345 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1346 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1347
[email protected]43410e92012-04-20 17:06:281348 // Wrapper for glViewport
1349 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1350
[email protected]07f54fcc2009-12-22 02:46:301351 // Wrapper for glUseProgram
1352 void DoUseProgram(GLuint program);
1353
[email protected]ae51d192010-04-27 00:48:031354 // Wrapper for glValidateProgram.
1355 void DoValidateProgram(GLuint program_client_id);
1356
[email protected]d2a0e1a2012-08-12 02:25:011357 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1358 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1359 void DoPopGroupMarkerEXT(void);
1360
[email protected]4e8a5b122010-05-08 22:00:101361 // Gets the number of values that will be returned by glGetXXX. Returns
1362 // false if pname is unknown.
1363 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1364
[email protected]07f54fcc2009-12-22 02:46:301365 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431366 bool IsDrawValid(
1367 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301368
[email protected]c13e1da62011-09-09 21:48:301369 // Returns true if successful, simulated will be true if attrib0 was
1370 // simulated.
[email protected]c6aef902012-02-14 03:31:421371 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431372 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]43410e92012-04-20 17:06:281373 void RestoreStateForAttrib(GLuint attrib);
[email protected]b1122982010-05-17 23:04:241374
[email protected]e56131d22013-07-28 16:14:111375 // If texture is a stream texture, this will update the stream to the newest
[email protected]e8dc5662013-10-17 23:28:291376 // buffer and bind the texture implicitly.
1377 void UpdateStreamTextureIfNeeded(Texture* texture, GLuint texture_unit_index);
[email protected]e56131d22013-07-28 16:14:111378
[email protected]91c94eb2013-10-22 10:32:541379 // If an image is bound to texture, this will call Will/DidUseTexImage
1380 // if needed.
1381 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1382 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1383
1384 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111385 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541386 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501387
[email protected]8fbedc02010-11-18 18:43:401388 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421389 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431390 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421391 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401392 void RestoreStateForSimulatedFixedAttribs();
1393
[email protected]c6aef902012-02-14 03:31:421394 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1395 // cases (primcount is 0 for non-instanced).
1396 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431397 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421398 bool instanced, GLenum mode, GLint first, GLsizei count,
1399 GLsizei primcount);
1400 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431401 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421402 bool instanced, GLenum mode, GLsizei count, GLenum type,
1403 int32 offset, GLsizei primcount);
1404
[email protected]61eeb33f2011-07-26 15:30:311405 GLenum GetBindTargetForSamplerType(GLenum type) {
1406 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461407 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1408 switch (type) {
1409 case GL_SAMPLER_2D:
1410 return GL_TEXTURE_2D;
1411 case GL_SAMPLER_CUBE:
1412 return GL_TEXTURE_CUBE_MAP;
1413 case GL_SAMPLER_EXTERNAL_OES:
1414 return GL_TEXTURE_EXTERNAL_OES;
1415 case GL_SAMPLER_2D_RECT_ARB:
1416 return GL_TEXTURE_RECTANGLE_ARB;
1417 }
1418
1419 NOTREACHED();
1420 return 0;
[email protected]61eeb33f2011-07-26 15:30:311421 }
1422
[email protected]8e3e0662010-08-23 18:46:301423 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061424 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1425 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301426 switch (target) {
1427 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451428 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341429 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301430 break;
[email protected]ebfb73c2012-08-15 02:37:451431 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341432 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301433 break;
1434 default:
1435 NOTREACHED();
1436 break;
1437 }
[email protected]4d8f0dd2013-03-09 14:37:061438 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301439 }
1440
[email protected]ed9f9cd2013-02-27 21:12:351441 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201442 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271443 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201444 switch (target) {
1445 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111446 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201447 break;
1448 default:
1449 NOTREACHED();
1450 break;
1451 }
[email protected]ee2a79c32013-03-10 03:50:271452 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201453 }
1454
[email protected]f7b85372010-02-03 01:11:371455 // Validates the program and location for a glGetUniform call and returns
1456 // a SizeResult setup to receive the result. Returns true if glGetUniform
1457 // should be called.
1458 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121459 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371460 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121461 error::Error* error, GLint* real_location, GLuint* service_id,
1462 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371463
[email protected]1078f912011-12-23 13:12:141464 // Computes the estimated memory used for the backbuffer and passes it to
1465 // the tracing system.
[email protected]260ddc4e2012-06-28 00:01:531466 size_t GetBackbufferMemoryTotal();
[email protected]1078f912011-12-23 13:12:141467
[email protected]a10b4a02012-11-26 23:09:501468 virtual bool WasContextLost() OVERRIDE;
[email protected]93a7d98f2013-07-11 00:04:221469 virtual bool WasContextLostByRobustnessExtension() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091470 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431471
[email protected]e51bdf32011-11-23 22:21:461472#if defined(OS_MACOSX)
1473 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1474#endif
1475
[email protected]81375742012-06-08 00:04:001476 // Validates the combination of texture parameters. For example validates that
1477 // for a given format the specific type, level and targets are valid.
1478 // Synthesizes the correct GL error if invalid. Returns true if valid.
1479 bool ValidateTextureParameters(
1480 const char* function_name,
1481 GLenum target, GLenum format, GLenum type, GLint level);
1482
[email protected]ad84a3a2012-06-08 21:42:431483 bool ValidateCompressedTexDimensions(
1484 const char* function_name,
1485 GLint level, GLsizei width, GLsizei height, GLenum format);
1486 bool ValidateCompressedTexFuncData(
1487 const char* function_name,
1488 GLsizei width, GLsizei height, GLenum format, size_t size);
1489 bool ValidateCompressedTexSubDimensions(
1490 const char* function_name,
1491 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1492 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351493 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431494
[email protected]ab09b612013-03-11 22:11:511495 void RenderWarning(const char* filename, int line, const std::string& msg);
1496 void PerformanceWarning(
1497 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011498
[email protected]62e155e2012-10-23 22:43:151499 const FeatureInfo::FeatureFlags& features() const {
1500 return feature_info_->feature_flags();
1501 }
1502
1503 const FeatureInfo::Workarounds& workarounds() const {
1504 return feature_info_->workarounds();
1505 }
1506
[email protected]a7266a92012-06-28 02:11:081507 bool ShouldDeferDraws() {
1508 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341509 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081510 surface_->DeferDraws();
1511 }
1512
[email protected]09e17272012-11-30 10:30:441513 bool ShouldDeferReads() {
1514 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341515 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441516 surface_->DeferDraws();
1517 }
1518
[email protected]5a36dc132013-07-23 23:17:551519 void ProcessPendingReadPixels();
1520 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1521
[email protected]96449d2c2009-11-25 00:01:321522 // Generate a member function prototype for each command in an automated and
1523 // typesafe way.
1524 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141525 Error Handle ## name( \
[email protected]ed9f9cd2013-02-27 21:12:351526 uint32 immediate_data_size, \
1527 const cmds::name& args); \
[email protected]96449d2c2009-11-25 00:01:321528
1529 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1530
1531 #undef GLES2_CMD_OP
1532
[email protected]2f2d7042010-04-14 21:45:581533 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381534 scoped_refptr<gfx::GLSurface> surface_;
1535 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021536
[email protected]a3ded6d2010-10-19 06:44:391537 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351538 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391539
[email protected]1d82e822013-04-10 21:32:321540 DebugMarkerManager debug_marker_manager_;
1541 Logger logger_;
1542
[email protected]e259eb412012-10-13 05:47:241543 // All the state for this context.
1544 ContextState state_;
1545
[email protected]34ff8b0c2010-10-01 20:06:021546 // Current width and height of the offscreen frame buffer.
1547 gfx::Size offscreen_size_;
1548
[email protected]96449d2c2009-11-25 00:01:321549 // Util to help with GL.
1550 GLES2Util util_;
1551
[email protected]43410e92012-04-20 17:06:281552 // unpack flip y as last set by glPixelStorei
1553 bool unpack_flip_y_;
1554
[email protected]6c75c712012-06-19 15:43:171555 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281556 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171557 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281558
[email protected]944b62f32012-09-27 02:20:461559 // Default vertex attribs manager, used when no VAOs are bound.
[email protected]ed9f9cd2013-02-27 21:12:351560 scoped_refptr<VertexAttribManager> default_vertex_attrib_manager_;
[email protected]07f54fcc2009-12-22 02:46:301561
[email protected]b1122982010-05-17 23:04:241562 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1563 GLuint attrib_0_buffer_id_;
1564
1565 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131566 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241567
[email protected]fc753442011-02-04 19:49:491568 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1569 bool attrib_0_buffer_matches_value_;
1570
[email protected]b1122982010-05-17 23:04:241571 // The size of attrib 0.
1572 GLsizei attrib_0_size_;
1573
[email protected]8fbedc02010-11-18 18:43:401574 // The buffer used to simulate GL_FIXED attribs.
1575 GLuint fixed_attrib_buffer_id_;
1576
1577 // The size of fiixed attrib buffer.
1578 GLsizei fixed_attrib_buffer_size_;
1579
[email protected]b9363b22010-06-09 22:06:151580 // The offscreen frame buffer that the client renders to. With EGL, the
1581 // depth and stencil buffers are separate. With regular GL there is a single
1582 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1583 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351584 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1585 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1586 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1587 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1588 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021589 GLenum offscreen_target_color_format_;
1590 GLenum offscreen_target_depth_format_;
1591 GLenum offscreen_target_stencil_format_;
1592 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561593 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351594
[email protected]de26b3c2011-08-03 21:54:271595 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351596 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1597 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491598 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351599 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271600
1601 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351602 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1603 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051604 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351605
[email protected]882ba1e22012-03-08 19:02:531606 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531607
[email protected]944b62f32012-09-27 02:20:461608 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1609
[email protected]729c0b42013-05-26 02:05:071610 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001611
[email protected]840a7e462013-02-27 01:29:511612 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481613
[email protected]e3932abb2013-03-13 00:01:371614 ShaderCacheCallback shader_cache_callback_;
1615
[email protected]85a4ac22013-05-31 01:58:471616 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421617
[email protected]32fe9aa2011-01-21 23:47:131618 // The format of the back buffer_
1619 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461620 bool back_buffer_has_depth_;
1621 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131622
[email protected]60f22d32012-12-12 00:31:581623 // Backbuffer attachments that are currently undefined.
1624 uint32 backbuffer_needs_clear_bits_;
1625
[email protected]a3a93e7b2010-08-28 00:48:561626 // The current decoder error.
1627 error::Error current_decoder_error_;
1628
[email protected]b1d2dcb2010-05-17 19:24:181629 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041630 scoped_refptr<ShaderTranslator> vertex_translator_;
1631 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181632
[email protected]e82fb792011-09-22 00:33:291633 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411634
[email protected]915a59a12010-09-30 21:29:111635 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051636 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351637 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051638
[email protected]65225772011-05-12 21:10:241639 int frame_number_;
1640
[email protected]706b69f2012-07-27 04:59:301641 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431642 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221643 bool reset_by_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431644
[email protected]f0d74742011-10-03 16:31:041645 // These flags are used to override the state of the shared feature_info_
1646 // member. Because the same FeatureInfo instance may be shared among many
1647 // contexts, the assumptions on the availablity of extensions in WebGL
1648 // contexts may be broken. These flags override the shared state to preserve
1649 // WebGL semantics.
1650 bool force_webgl_glsl_validation_;
1651 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491652 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131653 bool draw_buffers_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041654
[email protected]062c38b2012-01-18 03:25:101655 bool compile_shader_always_succeeds_;
1656
[email protected]cae20172012-12-07 00:06:191657 // Log extra info.
1658 bool service_logging_;
1659
[email protected]e51bdf32011-11-23 22:21:461660#if defined(OS_MACOSX)
1661 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap;
1662 TextureToIOSurfaceMap texture_to_io_surface_map_;
1663#endif
1664
[email protected]43410e92012-04-20 17:06:281665 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1666
[email protected]1868a342012-11-07 15:56:021667 // Cached values of the currently assigned viewport dimensions.
1668 GLsizei viewport_max_width_;
1669 GLsizei viewport_max_height_;
1670
[email protected]63b465922012-09-06 02:04:521671 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521672 base::TimeDelta total_processing_commands_time_;
1673
[email protected]c986af502013-08-14 01:04:441674 // States related to each manager.
1675 DecoderTextureState texture_state_;
1676 DecoderFramebufferState framebuffer_state_;
1677
[email protected]fb97b662013-02-20 23:02:141678 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131679 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
[email protected]94307712012-11-16 23:26:111680
[email protected]5a36dc132013-07-23 23:17:551681 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1682
[email protected]4a4c18b2013-09-13 22:50:101683 // Used to validate multisample renderbuffers if needed
1684 GLuint validation_texture_;
1685 GLuint validation_fbo_multisample_;
1686 GLuint validation_fbo_;
1687
[email protected]96449d2c2009-11-25 00:01:321688 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1689};
1690
[email protected]ab09b612013-03-11 22:11:511691ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301692 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511693 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301694 error_state_(error_state) {
1695 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351696}
1697
1698ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301699 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351700}
1701
[email protected]ce296892013-10-24 22:04:361702static void RestoreCurrentTexture2DBindings(ContextState* state) {
1703 TextureUnit& info = state->texture_units[0];
1704 GLuint last_id;
1705 if (info.bound_texture_2d.get()) {
1706 last_id = info.bound_texture_2d->service_id();
1707 } else {
1708 last_id = 0;
1709 }
1710
1711 glBindTexture(GL_TEXTURE_2D, last_id);
1712 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1713}
1714
1715ScopedTexture2DBinder::ScopedTexture2DBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351716 GLuint id)
[email protected]ce296892013-10-24 22:04:361717 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511718 ScopedGLErrorSuppressor suppressor(
[email protected]ce296892013-10-24 22:04:361719 "ScopedTexture2DBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351720
1721 // TODO(apatrick): Check if there are any other states that need to be reset
1722 // before binding a new texture.
1723 glActiveTexture(GL_TEXTURE0);
1724 glBindTexture(GL_TEXTURE_2D, id);
1725}
1726
1727ScopedTexture2DBinder::~ScopedTexture2DBinder() {
[email protected]ab09b612013-03-11 22:11:511728 ScopedGLErrorSuppressor suppressor(
[email protected]ce296892013-10-24 22:04:361729 "ScopedTexture2DBinder::dtor", state_->GetErrorState());
1730 RestoreCurrentTexture2DBindings(state_);
[email protected]6217d392010-03-25 22:08:351731}
1732
[email protected]18e785a2013-10-09 03:29:411733ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351734 GLuint id)
[email protected]18e785a2013-10-09 03:29:411735 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511736 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411737 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351738 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1739}
1740
1741ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511742 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411743 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
1744 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351745}
1746
1747ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1748 GLuint id)
1749 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511750 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301751 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351752 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451753 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351754}
1755
1756ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511757 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301758 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:301759 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351760}
1761
[email protected]34ff8b0c2010-10-01 20:06:021762ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271763 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521764 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:341765 resolve_and_bind_ = (
1766 decoder_->offscreen_target_frame_buffer_.get() &&
1767 decoder_->IsOffscreenBufferMultisampled() &&
1768 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
1769 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021770 if (!resolve_and_bind_)
1771 return;
1772
[email protected]ab09b612013-03-11 22:11:511773 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301774 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:021775 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1776 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271777 GLuint targetid;
1778 if (internal) {
1779 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1780 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351781 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271782 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351783 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:361784 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:271785 decoder_->offscreen_resolved_color_texture_->Create();
1786
1787 DCHECK(decoder_->offscreen_saved_color_format_);
1788 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091789 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1790 false);
[email protected]de26b3c2011-08-03 21:54:271791 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1792 decoder_->offscreen_resolved_color_texture_.get());
1793 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1794 GL_FRAMEBUFFER_COMPLETE) {
1795 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1796 << "because offscreen resolved FBO was incomplete.";
1797 return;
1798 }
1799 }
1800 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1801 } else {
1802 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1803 }
1804 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021805 const int width = decoder_->offscreen_size_.width();
1806 const int height = decoder_->offscreen_size_.height();
[email protected]8c3e68782010-10-27 16:41:181807 glDisable(GL_SCISSOR_TEST);
[email protected]57edfdad2012-02-07 04:57:151808 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021809 glBlitFramebufferANGLE(0, 0, width, height, 0, 0, width, height,
1810 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1811 } else {
1812 glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height,
1813 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1814 }
[email protected]de26b3c2011-08-03 21:54:271815 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021816}
1817
1818ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1819 if (!resolve_and_bind_)
1820 return;
1821
[email protected]ab09b612013-03-11 22:11:511822 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301823 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:021824 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:221825 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]8c3e68782010-10-27 16:41:181826 glEnable(GL_SCISSOR_TEST);
1827 }
[email protected]34ff8b0c2010-10-01 20:06:021828}
1829
[email protected]ce296892013-10-24 22:04:361830BackTexture::BackTexture(
1831 MemoryTracker* memory_tracker,
1832 ContextState* state)
1833 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
1834 state_(state),
[email protected]68e81a4a62012-12-13 01:16:481835 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251836 id_(0) {
[email protected]6217d392010-03-25 22:08:351837}
1838
[email protected]ed9f9cd2013-02-27 21:12:351839BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:351840 // This does not destroy the render texture because that would require that
1841 // the associated GL context was current. Just check that it was explicitly
1842 // destroyed.
1843 DCHECK_EQ(id_, 0u);
1844}
1845
[email protected]ed9f9cd2013-02-27 21:12:351846void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:301847 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:361848 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351849 Destroy();
1850 glGenTextures(1, &id_);
[email protected]ce296892013-10-24 22:04:361851 ScopedTexture2DBinder binder(state_, id_);
[email protected]3a4d0c52011-06-29 23:11:581852 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1853 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1854 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1855 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:161856
1857 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
1858 // never called on an offscreen context, no data will ever be uploaded to the
1859 // saved offscreen color texture (it is deferred until to when SwapBuffers
1860 // is called). My idea is that some nvidia drivers might have a bug where
1861 // deleting a texture that has never been populated might cause a
1862 // crash.
1863 glTexImage2D(
1864 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:481865
1866 bytes_allocated_ = 16u * 16u * 4u;
1867 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:351868}
1869
[email protected]ed9f9cd2013-02-27 21:12:351870bool BackTexture::AllocateStorage(
1871 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:351872 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:301873 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:361874 state_->GetErrorState());
1875 ScopedTexture2DBinder binder(state_, id_);
[email protected]678a73f2012-12-19 19:22:091876 uint32 image_size = 0;
1877 GLES2Util::ComputeImageDataSizes(
1878 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
1879 NULL, NULL);
1880
[email protected]7989c9e2013-01-23 06:39:261881 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
1882 return false;
1883 }
1884
[email protected]40d90a22013-04-09 03:39:551885 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:091886 if (zero) {
1887 zero_data.reset(new char[image_size]);
1888 memset(zero_data.get(), 0, image_size);
1889 }
[email protected]6217d392010-03-25 22:08:351890
[email protected]8f1d2aa2013-05-10 23:45:381891 glTexImage2D(GL_TEXTURE_2D,
1892 0, // mip level
1893 format,
1894 size.width(),
1895 size.height(),
1896 0, // border
1897 format,
1898 GL_UNSIGNED_BYTE,
1899 zero_data.get());
[email protected]6217d392010-03-25 22:08:351900
[email protected]d37231fa2010-04-09 21:16:021901 size_ = size;
1902
[email protected]1078f912011-12-23 13:12:141903 bool success = glGetError() == GL_NO_ERROR;
1904 if (success) {
[email protected]68e81a4a62012-12-13 01:16:481905 memory_tracker_.TrackMemFree(bytes_allocated_);
1906 bytes_allocated_ = image_size;
1907 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:141908 }
1909 return success;
[email protected]6217d392010-03-25 22:08:351910}
1911
[email protected]ed9f9cd2013-02-27 21:12:351912void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:351913 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:301914 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:361915 state_->GetErrorState());
1916 ScopedTexture2DBinder binder(state_, id_);
[email protected]6217d392010-03-25 22:08:351917 glCopyTexImage2D(GL_TEXTURE_2D,
1918 0, // level
[email protected]3a4d0c52011-06-29 23:11:581919 format,
[email protected]6217d392010-03-25 22:08:351920 0, 0,
1921 size.width(),
1922 size.height(),
1923 0); // border
1924}
1925
[email protected]ed9f9cd2013-02-27 21:12:351926void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:351927 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:301928 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:361929 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351930 glDeleteTextures(1, &id_);
1931 id_ = 0;
1932 }
[email protected]68e81a4a62012-12-13 01:16:481933 memory_tracker_.TrackMemFree(bytes_allocated_);
1934 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:351935}
1936
[email protected]ed9f9cd2013-02-27 21:12:351937void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:051938 id_ = 0;
1939}
1940
[email protected]d5a28e452013-10-10 01:01:401941BackRenderbuffer::BackRenderbuffer(
1942 RenderbufferManager* renderbuffer_manager,
1943 MemoryTracker* memory_tracker,
1944 ContextState* state)
1945 : renderbuffer_manager_(renderbuffer_manager),
1946 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
1947 state_(state),
[email protected]68e81a4a62012-12-13 01:16:481948 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251949 id_(0) {
[email protected]6217d392010-03-25 22:08:351950}
1951
[email protected]ed9f9cd2013-02-27 21:12:351952BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:351953 // This does not destroy the render buffer because that would require that
1954 // the associated GL context was current. Just check that it was explicitly
1955 // destroyed.
1956 DCHECK_EQ(id_, 0u);
1957}
1958
[email protected]ed9f9cd2013-02-27 21:12:351959void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:301960 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:401961 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351962 Destroy();
1963 glGenRenderbuffersEXT(1, &id_);
1964}
1965
[email protected]ed9f9cd2013-02-27 21:12:351966bool BackRenderbuffer::AllocateStorage(const gfx::Size& size, GLenum format,
1967 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:511968 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:401969 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
1970 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:261971
1972 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:401973 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:231974 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:261975 return false;
1976 }
1977
1978 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
1979 return false;
1980 }
1981
[email protected]34ff8b0c2010-10-01 20:06:021982 if (samples <= 1) {
1983 glRenderbufferStorageEXT(GL_RENDERBUFFER,
1984 format,
1985 size.width(),
1986 size.height());
1987 } else {
[email protected]57edfdad2012-02-07 04:57:151988 if (GLES2Decoder::IsAngle()) {
[email protected]34ff8b0c2010-10-01 20:06:021989 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER,
1990 samples,
1991 format,
1992 size.width(),
1993 size.height());
1994 } else {
1995 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER,
1996 samples,
1997 format,
1998 size.width(),
1999 size.height());
2000 }
2001 }
[email protected]1078f912011-12-23 13:12:142002 bool success = glGetError() == GL_NO_ERROR;
2003 if (success) {
[email protected]d5a28e452013-10-10 01:01:402004 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482005 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262006 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402007 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482008 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142009 }
2010 return success;
[email protected]6217d392010-03-25 22:08:352011}
2012
[email protected]ed9f9cd2013-02-27 21:12:352013void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352014 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302015 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402016 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352017 glDeleteRenderbuffersEXT(1, &id_);
2018 id_ = 0;
2019 }
[email protected]68e81a4a62012-12-13 01:16:482020 memory_tracker_.TrackMemFree(bytes_allocated_);
2021 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352022}
2023
[email protected]ed9f9cd2013-02-27 21:12:352024void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052025 id_ = 0;
2026}
2027
[email protected]ed9f9cd2013-02-27 21:12:352028BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352029 : decoder_(decoder),
2030 id_(0) {
2031}
2032
[email protected]ed9f9cd2013-02-27 21:12:352033BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352034 // This does not destroy the frame buffer because that would require that
2035 // the associated GL context was current. Just check that it was explicitly
2036 // destroyed.
2037 DCHECK_EQ(id_, 0u);
2038}
2039
[email protected]ed9f9cd2013-02-27 21:12:352040void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302041 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2042 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352043 Destroy();
2044 glGenFramebuffersEXT(1, &id_);
2045}
2046
[email protected]ed9f9cd2013-02-27 21:12:352047void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352048 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512049 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302050 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352051 ScopedFrameBufferBinder binder(decoder_, id_);
2052 GLuint attach_id = texture ? texture->id() : 0;
2053 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2054 GL_COLOR_ATTACHMENT0,
2055 GL_TEXTURE_2D,
2056 attach_id,
2057 0);
2058}
2059
[email protected]ed9f9cd2013-02-27 21:12:352060void BackFramebuffer::AttachRenderBuffer(GLenum target,
2061 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352062 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512063 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302064 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352065 ScopedFrameBufferBinder binder(decoder_, id_);
2066 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2067 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152068 target,
[email protected]6217d392010-03-25 22:08:352069 GL_RENDERBUFFER,
2070 attach_id);
2071}
2072
[email protected]ed9f9cd2013-02-27 21:12:352073void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352074 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302075 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2076 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352077 glDeleteFramebuffersEXT(1, &id_);
2078 id_ = 0;
2079 }
2080}
2081
[email protected]ed9f9cd2013-02-27 21:12:352082void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052083 id_ = 0;
2084}
2085
[email protected]ed9f9cd2013-02-27 21:12:352086GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352087 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302088 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2089 decoder_->GetErrorState());
[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]34ff8b0c2010-10-01 20:06:022111 offscreen_target_color_format_(0),
2112 offscreen_target_depth_format_(0),
2113 offscreen_target_stencil_format_(0),
2114 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562115 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052116 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132117 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462118 back_buffer_has_depth_(false),
2119 back_buffer_has_stencil_(false),
[email protected]60f22d32012-12-12 00:31:582120 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562121 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052122 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112123 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002124 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432125 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302126 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512127 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222128 reset_by_robustness_extension_(false),
[email protected]f0d74742011-10-03 16:31:042129 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102130 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492131 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132132 draw_buffers_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282133 compile_shader_always_succeeds_(false),
[email protected]cae20172012-12-07 00:06:192134 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2135 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022136 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102137 viewport_max_height_(0),
2138 validation_texture_(0),
2139 validation_fbo_multisample_(0),
2140 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572141 DCHECK(group);
2142
[email protected]b1122982010-05-17 23:04:242143 attrib_0_value_.v[0] = 0.0f;
2144 attrib_0_value_.v[1] = 0.0f;
2145 attrib_0_value_.v[2] = 0.0f;
2146 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152147
[email protected]c2f8c8402010-12-06 18:07:242148 // The shader translator is used for WebGL even when running on EGL
2149 // because additional restrictions are needed (like only enabling
2150 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562151 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2152 // the empty string to CompileShader and this is not a valid shader.
2153 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002154 CommandLine::ForCurrentProcess()->HasSwitch(
2155 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152156 use_shader_translator_ = false;
2157 }
[email protected]473c01ccb2011-06-07 01:33:302158
[email protected]a39370652012-09-25 21:52:132159 // TODO(gman): Consider setting this based on GPU and/or driver.
[email protected]473c01ccb2011-06-07 01:33:302160 if (IsAngle()) {
[email protected]c986af502013-08-14 01:04:442161 texture_state_.teximage2d_faster_than_texsubimage2d = false;
[email protected]473c01ccb2011-06-07 01:33:302162 }
[email protected]96449d2c2009-11-25 00:01:322163}
2164
[email protected]80eb6b52012-01-19 00:14:412165GLES2DecoderImpl::~GLES2DecoderImpl() {
2166}
2167
[email protected]c410da802011-03-14 19:17:412168bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382169 const scoped_refptr<gfx::GLSurface>& surface,
2170 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232171 bool offscreen,
[email protected]c410da802011-03-14 19:17:412172 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292173 const DisallowedFeatures& disallowed_features,
[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();
[email protected]8f9b8dd2013-09-12 18:05:132181 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]fb97b662013-02-20 23:02:142182
[email protected]e844ae22012-01-14 03:36:262183 if (CommandLine::ForCurrentProcess()->HasSwitch(
2184 switches::kEnableGPUDebugging)) {
2185 set_debug(true);
2186 }
2187
[email protected]39ba4f02012-03-26 01:16:002188 if (CommandLine::ForCurrentProcess()->HasSwitch(
2189 switches::kEnableGPUCommandLogging)) {
2190 set_log_commands(true);
2191 }
2192
[email protected]062c38b2012-01-18 03:25:102193 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2194 switches::kCompileShaderAlwaysSucceeds);
2195
[email protected]f62a5ab2011-05-23 20:34:152196
[email protected]63c9b052012-05-17 18:27:382197 // Take ownership of the context and surface. The surface can be replaced with
2198 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382199 context_ = context;
[email protected]63c9b052012-05-17 18:27:382200 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182201
[email protected]956aec52013-09-05 15:41:192202 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222203 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392204 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422205 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382206 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032207 return false;
[email protected]a3ded6d2010-10-19 06:44:392208 }
[email protected]b64c24952012-04-19 03:20:272209 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282210
[email protected]e82fb792011-09-22 00:33:292211 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502212
[email protected]af6380962012-11-29 23:24:132213 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]944b62f32012-09-27 02:20:462214 default_vertex_attrib_manager_ = new VertexAttribManager();
2215 default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs());
2216
[email protected]ab4fd7282012-10-12 16:25:572217 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call
2218 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322219
[email protected]7cd76fd2013-06-02 21:11:112220 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]944b62f32012-09-27 02:20:462221 vertex_array_manager_.reset(new VertexArrayManager());
[email protected]882ba1e22012-03-08 19:02:532222
[email protected]302ce6d2011-07-07 23:28:112223 util_.set_num_compressed_texture_formats(
2224 validators_->compressed_texture_format.GetValues().size());
2225
[email protected]1071e572011-02-09 20:00:122226 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2227 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2228 // OpenGL ES 2.0 does not have this issue.
2229 glEnableVertexAttribArray(0);
2230 }
[email protected]b1122982010-05-17 23:04:242231 glGenBuffersARB(1, &attrib_0_buffer_id_);
2232 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2233 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2234 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402235 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082236
[email protected]1868a342012-11-07 15:56:022237 state_.texture_units.resize(group_->max_texture_units());
2238 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492239 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312240 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492241 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152242 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492243 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072244 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492245 state_.texture_units[tt].bound_texture_external_oes = ref;
2246 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref->service_id());
[email protected]61eeb33f2011-07-26 15:30:312247 }
[email protected]62e155e2012-10-23 22:43:152248 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492249 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072250 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492251 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
2252 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref->service_id());
[email protected]e51bdf32011-11-23 22:21:462253 }
[email protected]370eaf12013-05-18 09:19:492254 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2255 state_.texture_units[tt].bound_texture_cube_map = ref;
2256 glBindTexture(GL_TEXTURE_CUBE_MAP, ref->service_id());
2257 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2258 state_.texture_units[tt].bound_texture_2d = ref;
2259 glBindTexture(GL_TEXTURE_2D, ref->service_id());
[email protected]1958e0e2010-04-22 05:17:152260 }
[email protected]00f893d2010-08-24 18:55:492261 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502262 CHECK_GL_ERROR();
2263
[email protected]763eaf72013-08-16 00:58:562264 ContextCreationAttribHelper attrib_parser;
[email protected]297ca1c2011-06-20 23:08:462265 if (!attrib_parser.Parse(attribs))
2266 return false;
[email protected]41c56362011-06-14 16:47:432267
[email protected]069944672012-04-25 20:52:232268 if (offscreen) {
[email protected]34ff8b0c2010-10-01 20:06:022269 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
[email protected]b0609652012-12-14 07:24:542270 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022271 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432272 // max_sample_count must be initialized to a sane value. If
2273 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2274 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022275 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2276 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2277 max_sample_count);
2278 } else {
2279 offscreen_target_samples_ = 1;
2280 }
[email protected]8a61d872012-01-20 12:43:562281 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
[email protected]34ff8b0c2010-10-01 20:06:022282
2283 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2284 const bool rgb8_supported =
2285 context_->HasExtension("GL_OES_rgb8_rgba8");
2286 // The only available default render buffer formats in GLES2 have very
2287 // little precision. Don't enable multisampling unless 8-bit render
2288 // buffer formats are available--instead fall back to 8-bit textures.
2289 if (rgb8_supported && offscreen_target_samples_ > 1) {
2290 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2291 GL_RGBA8 : GL_RGB8;
2292 } else {
2293 offscreen_target_samples_ = 1;
2294 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2295 GL_RGBA : GL_RGB;
2296 }
2297
2298 // ANGLE only supports packed depth/stencil formats, so use it if it is
2299 // available.
2300 const bool depth24_stencil8_supported =
2301 context_->HasExtension("GL_OES_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272302 VLOG(1) << "GL_OES_packed_depth_stencil "
2303 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]71ee3642010-10-14 18:08:002304 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2305 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022306 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2307 offscreen_target_stencil_format_ = 0;
2308 } else {
2309 // It may be the case that this depth/stencil combination is not
2310 // supported, but this will be checked later by CheckFramebufferStatus.
2311 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2312 GL_DEPTH_COMPONENT16 : 0;
2313 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2314 GL_STENCIL_INDEX8 : 0;
2315 }
2316 } else {
2317 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2318 GL_RGBA : GL_RGB;
2319
2320 // If depth is requested at all, use the packed depth stencil format if
2321 // it's available, as some desktop GL drivers don't support any non-packed
2322 // formats for depth attachments.
2323 const bool depth24_stencil8_supported =
2324 context_->HasExtension("GL_EXT_packed_depth_stencil");
[email protected]d366c482010-10-20 00:11:272325 VLOG(1) << "GL_EXT_packed_depth_stencil "
2326 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022327
[email protected]71ee3642010-10-14 18:08:002328 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2329 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022330 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2331 offscreen_target_stencil_format_ = 0;
2332 } else {
2333 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2334 GL_DEPTH_COMPONENT : 0;
2335 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2336 GL_STENCIL_INDEX : 0;
2337 }
2338 }
2339
[email protected]97872062010-11-03 19:07:052340 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2341 GL_RGBA : GL_RGB;
2342
[email protected]6217d392010-03-25 22:08:352343 // Create the target frame buffer. This is the one that the client renders
2344 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352345 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352346 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022347 // Due to GLES2 format limitations, either the color texture (for
2348 // non-multisampling) or the color render buffer (for multisampling) will be
2349 // attached to the offscreen frame buffer. The render buffer has more
2350 // limited formats available to it, but the texture can't do multisampling.
2351 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402352 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2353 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022354 offscreen_target_color_render_buffer_->Create();
2355 } else {
[email protected]ce296892013-10-24 22:04:362356 offscreen_target_color_texture_.reset(new BackTexture(
2357 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022358 offscreen_target_color_texture_->Create();
2359 }
[email protected]d5a28e452013-10-10 01:01:402360 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2361 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152362 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402363 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2364 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152365 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352366
2367 // Create the saved offscreen texture. The target frame buffer is copied
2368 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352369 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022370 offscreen_saved_frame_buffer_->Create();
2371 //
[email protected]ce296892013-10-24 22:04:362372 offscreen_saved_color_texture_.reset(new BackTexture(
2373 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352374 offscreen_saved_color_texture_->Create();
2375
[email protected]6217d392010-03-25 22:08:352376 // Allocate the render buffers at their initial size and check the status
2377 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592378 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012379 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382380 Destroy(true);
[email protected]6217d392010-03-25 22:08:352381 return false;
2382 }
2383
[email protected]678a73f2012-12-19 19:22:092384 // Allocate the offscreen saved color texture.
2385 DCHECK(offscreen_saved_color_format_);
2386 offscreen_saved_color_texture_->AllocateStorage(
2387 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2388
2389 offscreen_saved_frame_buffer_->AttachRenderTexture(
2390 offscreen_saved_color_texture_.get());
2391 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2392 GL_FRAMEBUFFER_COMPLETE) {
2393 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2394 Destroy(true);
2395 return false;
2396 }
2397
[email protected]6217d392010-03-25 22:08:352398 // Bind to the new default frame buffer (the offscreen target frame buffer).
2399 // This should now be associated with ID zero.
2400 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102401 } else {
2402 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2403 // These are NOT if the back buffer has these proprorties. They are
2404 // if we want the command buffer to enforce them regardless of what
2405 // the real backbuffer is assuming the real back buffer gives us more than
2406 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2407 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2408 // can't do anything about that.
2409
2410 GLint v = 0;
2411 glGetIntegerv(GL_ALPHA_BITS, &v);
2412 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2413 // user requested RGB then RGB. If the user did not specify a preference
2414 // than use whatever we were given. Same for DEPTH and STENCIL.
2415 back_buffer_color_format_ =
2416 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2417 glGetIntegerv(GL_DEPTH_BITS, &v);
2418 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2419 glGetIntegerv(GL_STENCIL_BITS, &v);
2420 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
[email protected]6217d392010-03-25 22:08:352421 }
2422
[email protected]76a0ee102010-04-07 21:03:042423 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2424 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2425 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372426 // mailing list archives. It also implicitly enables the desktop GL
2427 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2428 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152429 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2430 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372431 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152432 }
[email protected]de17df392010-04-23 21:09:412433
[email protected]706b69f2012-07-27 04:59:302434 has_robustness_extension_ =
2435 context->HasExtension("GL_ARB_robustness") ||
2436 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432437
[email protected]c2f8c8402010-12-06 18:07:242438 if (!InitializeShaderTranslator()) {
2439 return false;
[email protected]de17df392010-04-23 21:09:412440 }
[email protected]76a0ee102010-04-07 21:03:042441
[email protected]e259eb412012-10-13 05:47:242442 state_.viewport_width = size.width();
2443 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282444
[email protected]5904806b2012-05-08 18:10:222445 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282446 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022447 viewport_max_width_ = viewport_params[0];
2448 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282449
[email protected]88a61bf2012-10-27 13:00:422450 state_.scissor_width = state_.viewport_width;
2451 state_.scissor_height = state_.viewport_height;
2452
[email protected]11f3e702012-06-19 19:00:012453 // Set all the default state because some GL drivers get it wrong.
[email protected]f731b9462012-10-30 00:35:222454 state_.InitCapabilities();
2455 state_.InitState();
[email protected]e259eb412012-10-13 05:47:242456 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012457
2458 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2459 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2460 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2461 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2462
[email protected]88cfd132013-07-11 00:59:002463 bool call_gl_clear = true;
2464#if defined(OS_ANDROID)
2465 // Temporary workaround for Android WebView because this clear ignores the
2466 // clip and corrupts that external UI of the App. Not calling glClear is ok
2467 // because the system already clears the buffer before each draw. Proper
2468 // fix might be setting the scissor clip properly before initialize. See
2469 // crbug.com/259023 for details.
2470 call_gl_clear = surface_->GetHandle();
2471#endif
2472 if (call_gl_clear) {
2473 // Clear the backbuffer.
2474 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2475 }
[email protected]561cc0a62013-05-07 18:34:452476
[email protected]62e155e2012-10-23 22:43:152477 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462478 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2479 }
[email protected]dd289a5d62012-06-30 22:05:462480
[email protected]9b753992013-04-27 02:04:412481 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2482 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242483 }
[email protected]85cb4682013-04-20 00:54:242484
[email protected]40245ccf2013-11-13 04:00:492485 if (feature_info_->workarounds().release_image_after_use) {
2486 image_manager()->SetReleaseAfterUse();
2487 }
2488
[email protected]97419c02013-04-10 02:52:382489 // Only compositor contexts are known to use only the subset of GL
2490 // that can be safely migrated between the iGPU and the dGPU. Mark
2491 // those contexts as safe to forcibly transition between the GPUs.
2492 // http://crbug.com/180876, http://crbug.com/227228
2493 if (!offscreen)
2494 context_->SetSafeToForceGpuSwitch();
2495
[email protected]85a4ac22013-05-31 01:58:472496 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072497 AsyncPixelTransferManager::Create(context.get()));
2498 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592499
[email protected]91c94eb2013-10-22 10:32:542500 framebuffer_manager()->AddObserver(this);
2501
[email protected]246a70452010-03-05 21:53:502502 return true;
[email protected]96449d2c2009-11-25 00:01:322503}
2504
[email protected]302ce6d2011-07-07 23:28:112505void GLES2DecoderImpl::UpdateCapabilities() {
2506 util_.set_num_compressed_texture_formats(
2507 validators_->compressed_texture_format.GetValues().size());
2508 util_.set_num_shader_binary_formats(
2509 validators_->shader_binary_format.GetValues().size());
2510}
2511
[email protected]c2f8c8402010-12-06 18:07:242512bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442513 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2514
[email protected]c2f8c8402010-12-06 18:07:242515 if (!use_shader_translator_) {
2516 return true;
2517 }
2518 ShBuiltInResources resources;
2519 ShInitBuiltInResources(&resources);
2520 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2521 resources.MaxVertexUniformVectors =
2522 group_->max_vertex_uniform_vectors();
2523 resources.MaxVaryingVectors = group_->max_varying_vectors();
2524 resources.MaxVertexTextureImageUnits =
2525 group_->max_vertex_texture_image_units();
2526 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2527 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2528 resources.MaxFragmentUniformVectors =
2529 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492530 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242531 resources.MaxExpressionComplexity = 256;
2532 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042533
[email protected]9e98f61b2013-03-05 02:21:142534#if (ANGLE_SH_VERSION >= 110)
[email protected]46c86752013-05-21 05:08:392535 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212536 GLint precision = 0;
2537 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2538 range, &precision);
[email protected]448e459e2013-06-12 17:00:412539 resources.FragmentPrecisionHigh =
2540 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142541#endif
2542
[email protected]f0d74742011-10-03 16:31:042543 if (force_webgl_glsl_validation_) {
2544 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492545 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132546 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:442547 if (!draw_buffers_explicitly_enabled_)
2548 resources.MaxDrawBuffers = 1;
[email protected]f0d74742011-10-03 16:31:042549 } else {
2550 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152551 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462552 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152553 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062554 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152555 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492556 resources.EXT_draw_buffers =
2557 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492558 resources.EXT_frag_depth =
2559 features().ext_frag_depth ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042560 }
2561
[email protected]26b61442013-03-17 16:12:012562 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2563 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052564 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022565#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]6aedcdc2013-01-24 01:25:052566 resources.HashFunction = &CityHashForAngle;
[email protected]3d944a82013-02-12 19:09:022567#else
2568 resources.HashFunction = &CityHash64;
2569#endif
[email protected]6aedcdc2013-01-24 01:25:052570 else
2571 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122572 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2573 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2574 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:212575 int driver_bug_workarounds = 0;
2576 if (workarounds().needs_glsl_built_in_function_emulation)
2577 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:542578 if (workarounds().init_gl_position_in_vertex_shader)
2579 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:112580 if (workarounds().unfold_short_circuit_as_ternary_operation)
2581 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]87fb6ab2012-06-13 22:28:042582
2583 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance();
2584 vertex_translator_ = cache->GetTranslator(
2585 SH_VERTEX_SHADER, shader_spec, &resources,
[email protected]a6739bc2013-09-07 04:45:212586 implementation_type,
2587 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042588 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242589 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382590 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242591 return false;
2592 }
[email protected]87fb6ab2012-06-13 22:28:042593
2594 fragment_translator_ = cache->GetTranslator(
2595 SH_FRAGMENT_SHADER, shader_spec, &resources,
[email protected]a6739bc2013-09-07 04:45:212596 implementation_type,
2597 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042598 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242599 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382600 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242601 return false;
2602 }
2603 return true;
2604}
2605
[email protected]ae51d192010-04-27 00:48:032606bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472607 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352608 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032609 return false;
2610 }
2611 }
[email protected]40d90a22013-04-09 03:39:552612 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032613 glGenBuffersARB(n, service_ids.get());
2614 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352615 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032616 }
2617 return true;
2618}
2619
2620bool GLES2DecoderImpl::GenFramebuffersHelper(
2621 GLsizei n, const GLuint* client_ids) {
2622 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352623 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032624 return false;
2625 }
2626 }
[email protected]40d90a22013-04-09 03:39:552627 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032628 glGenFramebuffersEXT(n, service_ids.get());
2629 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352630 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032631 }
2632 return true;
2633}
2634
2635bool GLES2DecoderImpl::GenRenderbuffersHelper(
2636 GLsizei n, const GLuint* client_ids) {
2637 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352638 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032639 return false;
2640 }
2641 }
[email protected]40d90a22013-04-09 03:39:552642 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032643 glGenRenderbuffersEXT(n, service_ids.get());
2644 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352645 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032646 }
2647 return true;
2648}
2649
2650bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2651 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352652 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032653 return false;
2654 }
2655 }
[email protected]40d90a22013-04-09 03:39:552656 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032657 glGenTextures(n, service_ids.get());
2658 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352659 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032660 }
2661 return true;
2662}
2663
2664void GLES2DecoderImpl::DeleteBuffersHelper(
2665 GLsizei n, const GLuint* client_ids) {
2666 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212667 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102668 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242669 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:112670 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:242671 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102672 }
[email protected]ed9f9cd2013-02-27 21:12:352673 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032674 }
[email protected]a93bb842010-02-16 23:03:472675 }
[email protected]07f54fcc2009-12-22 02:46:302676}
2677
[email protected]ae51d192010-04-27 00:48:032678void GLES2DecoderImpl::DeleteFramebuffersHelper(
2679 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452680 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152681 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112682
[email protected]a25fa872010-03-25 02:57:582683 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352684 Framebuffer* framebuffer =
2685 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102686 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:342687 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
2688 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]c986af502013-08-14 01:04:442689 framebuffer_state_.clear_state_dirty = true;
[email protected]ebfb73c2012-08-15 02:37:452690 GLenum target = supports_separate_framebuffer_binds ?
2691 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112692 glBindFramebufferEXT(target, GetBackbufferServiceId());
2693 }
[email protected]9d3b2e12013-10-02 01:04:342694 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
2695 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452696 GLenum target = supports_separate_framebuffer_binds ?
2697 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112698 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462699 }
[email protected]70d34263c2013-01-09 00:27:452700 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352701 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032702 }
[email protected]a25fa872010-03-25 02:57:582703 }
[email protected]07f54fcc2009-12-22 02:46:302704}
2705
[email protected]ae51d192010-04-27 00:48:032706void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2707 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452708 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152709 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582710 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352711 Renderbuffer* renderbuffer =
2712 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102713 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:112714 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:242715 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102716 }
2717 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452718 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:342719 if (framebuffer_state_.bound_read_framebuffer.get()) {
2720 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112721 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102722 }
[email protected]9d3b2e12013-10-02 01:04:342723 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2724 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112725 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102726 }
2727 } else {
[email protected]9d3b2e12013-10-02 01:04:342728 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2729 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112730 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102731 }
2732 }
[email protected]c986af502013-08-14 01:04:442733 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:352734 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032735 }
[email protected]a25fa872010-03-25 02:57:582736 }
[email protected]07f54fcc2009-12-22 02:46:302737}
2738
[email protected]ae51d192010-04-27 00:48:032739void GLES2DecoderImpl::DeleteTexturesHelper(
2740 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452741 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152742 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472743 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:492744 TextureRef* texture_ref = GetTexture(client_ids[ii]);
2745 if (texture_ref) {
2746 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:102747 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:442748 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:462749 }
[email protected]370eaf12013-05-18 09:19:492750 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:022751 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:492752 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102753 }
2754 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452755 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:342756 if (framebuffer_state_.bound_read_framebuffer.get()) {
2757 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112758 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102759 }
[email protected]9d3b2e12013-10-02 01:04:342760 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2761 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112762 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102763 }
2764 } else {
[email protected]9d3b2e12013-10-02 01:04:342765 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2766 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112767 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102768 }
2769 }
[email protected]e51bdf32011-11-23 22:21:462770#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:072771 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:462772 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
2773 ReleaseIOSurfaceForTexture(service_id);
2774 }
2775#endif
[email protected]ed9f9cd2013-02-27 21:12:352776 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032777 }
[email protected]a93bb842010-02-16 23:03:472778 }
[email protected]07f54fcc2009-12-22 02:46:302779}
2780
[email protected]43f28f832010-02-03 02:28:482781// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:322782
[email protected]eb54a562010-01-20 21:55:182783bool GLES2DecoderImpl::MakeCurrent() {
[email protected]63c9b052012-05-17 18:27:382784 if (!context_.get() || !context_->MakeCurrent(surface_.get()))
2785 return false;
2786
2787 if (WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:432788 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:292789
2790 // Some D3D drivers cannot recover from device lost in the GPU process
2791 // sandbox. Allow a new GPU process to launch.
2792 if (workarounds().exit_on_context_lost) {
2793 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
2794 << " a D3D device in the Chrome GPU process sandbox.";
[email protected]6eb775352013-08-27 05:57:162795#if defined(OS_WIN)
2796 base::win::SetShouldCrashOnProcessDetach(false);
2797#endif
[email protected]e9f0ca82013-04-01 23:52:292798 exit(0);
2799 }
2800
[email protected]63c9b052012-05-17 18:27:382801 return false;
[email protected]38d139d2011-07-14 00:38:432802 }
2803
[email protected]69a8701e2013-03-07 21:31:092804 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:092805
[email protected]9b753992013-04-27 02:04:412806 // Rebind the FBO if it was unbound by the context.
2807 if (workarounds().unbind_fbo_on_context_switch)
2808 RestoreFramebufferBindings();
2809
[email protected]c986af502013-08-14 01:04:442810 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:492811
[email protected]69a8701e2013-03-07 21:31:092812 return true;
2813}
2814
2815void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:552816 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:322817 if (engine() && query_manager_.get())
2818 query_manager_->ProcessPendingTransferQueries();
2819
[email protected]5b3a8e02013-03-13 05:36:442820 // TODO(epenner): Is there a better place to do this?
2821 // This needs to occur before we execute any batch of commands
2822 // from the client, as the client may have recieved an async
2823 // completion while issuing those commands.
2824 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:482825 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:182826}
2827
[email protected]a96a6022011-11-04 00:58:122828void GLES2DecoderImpl::ReleaseCurrent() {
2829 if (context_.get())
2830 context_->ReleaseCurrent(surface_.get());
2831}
2832
[email protected]8e3e0662010-08-23 18:46:302833static void RebindCurrentFramebuffer(
2834 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:062835 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:242836 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:062837 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:462838
[email protected]a3783712012-01-20 22:18:242839 if (framebuffer_id == 0) {
2840 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:302841 }
[email protected]297ca1c2011-06-20 23:08:462842
[email protected]8e3e0662010-08-23 18:46:302843 glBindFramebufferEXT(target, framebuffer_id);
2844}
2845
2846void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:442847 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:462848
[email protected]62e155e2012-10-23 22:43:152849 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:302850 RebindCurrentFramebuffer(
2851 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:342852 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242853 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302854 } else {
2855 RebindCurrentFramebuffer(
2856 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:342857 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242858 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302859 RebindCurrentFramebuffer(
2860 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:342861 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242862 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302863 }
[email protected]70d34263c2013-01-09 00:27:452864 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:302865}
2866
[email protected]0d6bfdc2011-11-02 01:32:202867bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:352868 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:202869 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:102870 if (!framebuffer) {
[email protected]60f22d32012-12-12 00:31:582871 if (backbuffer_needs_clear_bits_) {
2872 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
2873 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
2874 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2875 glClearStencil(0);
2876 glStencilMask(-1);
2877 glClearDepth(1.0f);
2878 glDepthMask(true);
2879 glDisable(GL_SCISSOR_TEST);
2880 glClear(backbuffer_needs_clear_bits_);
2881 backbuffer_needs_clear_bits_ = 0;
2882 RestoreClearState();
2883 }
[email protected]0d6bfdc2011-11-02 01:32:202884 return true;
2885 }
2886
[email protected]968351b2011-12-20 08:26:512887 if (framebuffer_manager()->IsComplete(framebuffer)) {
2888 return true;
2889 }
2890
[email protected]0d6bfdc2011-11-02 01:32:202891 GLenum completeness = framebuffer->IsPossiblyComplete();
2892 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512893 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432894 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:272895 return false;
2896 }
[email protected]0d6bfdc2011-11-02 01:32:202897
2898 // Are all the attachments cleared?
2899 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
2900 texture_manager()->HaveUnclearedMips()) {
2901 if (!framebuffer->IsCleared()) {
2902 // Can we clear them?
[email protected]73276522012-11-09 05:50:202903 if (framebuffer->GetStatus(texture_manager(), target) !=
2904 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512905 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432906 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2907 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:202908 return false;
2909 }
2910 ClearUnclearedAttachments(target, framebuffer);
2911 }
2912 }
2913
[email protected]968351b2011-12-20 08:26:512914 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:202915 if (framebuffer->GetStatus(texture_manager(), target) !=
2916 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512917 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432918 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
2919 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:512920 return false;
2921 }
2922 framebuffer_manager()->MarkAsComplete(framebuffer);
2923 }
2924
[email protected]0d6bfdc2011-11-02 01:32:202925 // NOTE: At this point we don't know if the framebuffer is complete but
2926 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:272927 return true;
2928}
2929
[email protected]0d6bfdc2011-11-02 01:32:202930bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:152931 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:512932 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:342933 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
2934 func_name);
[email protected]28718a92013-04-04 12:12:512935
2936 if (valid)
2937 OnUseFramebuffer();
2938
2939 return valid;
[email protected]0d6bfdc2011-11-02 01:32:202940 }
[email protected]9d3b2e12013-10-02 01:04:342941 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:112942 GL_DRAW_FRAMEBUFFER_EXT,
2943 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:342944 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:112945 GL_READ_FRAMEBUFFER_EXT,
2946 func_name);
[email protected]0d6bfdc2011-11-02 01:32:202947}
2948
[email protected]8e3e0662010-08-23 18:46:302949gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:352950 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452951 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202952 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:352953 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:202954 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:262955 if (attachment) {
2956 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:502957 }
[email protected]9edc6b22010-12-23 02:00:262958 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:022959 } else if (offscreen_target_frame_buffer_.get()) {
2960 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:352961 } else {
[email protected]f62a5ab2011-05-23 20:34:152962 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:022963 }
[email protected]246a70452010-03-05 21:53:502964}
2965
[email protected]9edc6b22010-12-23 02:00:262966GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:352967 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452968 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202969 if (framebuffer != NULL) {
2970 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:462971 } else if (offscreen_target_frame_buffer_.get()) {
2972 return offscreen_target_color_format_;
2973 } else {
2974 return back_buffer_color_format_;
2975 }
2976}
2977
2978GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:352979 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:452980 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:202981 if (framebuffer != NULL) {
2982 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:262983 } else if (offscreen_target_frame_buffer_.get()) {
2984 return offscreen_target_color_format_;
2985 } else {
[email protected]32fe9aa2011-01-21 23:47:132986 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:262987 }
2988}
2989
[email protected]9a5afa432011-07-22 18:16:392990void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:512991 if (!offscreen_saved_color_texture_info_.get())
2992 return;
2993 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
2994 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
2995 texture_manager()->SetLevelInfo(
2996 offscreen_saved_color_texture_info_.get(),
2997 GL_TEXTURE_2D,
2998 0, // level
2999 GL_RGBA,
3000 offscreen_size_.width(),
3001 offscreen_size_.height(),
3002 1, // depth
3003 0, // border
3004 GL_RGBA,
3005 GL_UNSIGNED_BYTE,
3006 true);
3007 texture_manager()->SetParameter(
3008 "UpdateParentTextureInfo",
3009 GetErrorState(),
3010 offscreen_saved_color_texture_info_.get(),
3011 GL_TEXTURE_MAG_FILTER,
3012 GL_NEAREST);
3013 texture_manager()->SetParameter(
3014 "UpdateParentTextureInfo",
3015 GetErrorState(),
3016 offscreen_saved_color_texture_info_.get(),
3017 GL_TEXTURE_MIN_FILTER,
3018 GL_NEAREST);
3019 texture_manager()->SetParameter(
3020 "UpdateParentTextureInfo",
3021 GetErrorState(),
3022 offscreen_saved_color_texture_info_.get(),
3023 GL_TEXTURE_WRAP_S,
3024 GL_CLAMP_TO_EDGE);
3025 texture_manager()->SetParameter(
3026 "UpdateParentTextureInfo",
3027 GetErrorState(),
3028 offscreen_saved_color_texture_info_.get(),
3029 GL_TEXTURE_WRAP_T,
3030 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443031 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3032 &state_, target);
[email protected]2ad674132013-06-05 07:48:513033 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353034}
3035
[email protected]799b4b22011-08-22 17:09:593036void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073037 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523038 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003039}
3040
[email protected]1d82e822013-04-10 21:32:323041Logger* GLES2DecoderImpl::GetLogger() {
3042 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523043}
3044
[email protected]d3eba342013-04-18 21:11:503045ErrorState* GLES2DecoderImpl::GetErrorState() {
3046 return state_.GetErrorState();
3047}
3048
[email protected]e3932abb2013-03-13 00:01:373049void GLES2DecoderImpl::SetShaderCacheCallback(
3050 const ShaderCacheCallback& callback) {
3051 shader_cache_callback_ = callback;
3052}
3053
[email protected]840a7e462013-02-27 01:29:513054void GLES2DecoderImpl::SetWaitSyncPointCallback(
3055 const WaitSyncPointCallback& callback) {
3056 wait_sync_point_callback_ = callback;
3057}
3058
[email protected]85a4ac22013-05-31 01:58:473059AsyncPixelTransferManager*
3060 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3061 return async_pixel_transfer_manager_.get();
3062}
3063
3064void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3065 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593066}
3067
[email protected]498b5c072013-06-04 19:30:073068void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3069 AsyncPixelTransferManager* manager) {
3070 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3071}
3072
[email protected]1318e922010-09-17 22:03:163073bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3074 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493075 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3076 if (texture_ref) {
3077 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163078 return true;
3079 }
3080 return false;
3081}
3082
[email protected]63b465922012-09-06 02:04:523083uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443084 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483085 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523086}
3087
3088base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443089 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483090 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523091}
3092
3093base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3094 return total_processing_commands_time_;
3095}
3096
[email protected]dc25dda2012-09-27 21:36:303097void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3098 total_processing_commands_time_ += time;
3099}
3100
[email protected]63c9b052012-05-17 18:27:383101void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063102 if (!initialized())
3103 return;
3104
[email protected]63c9b052012-05-17 18:27:383105 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053106
[email protected]80eb6b52012-01-19 00:14:413107 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243108 state_.vertex_attrib_manager = NULL;
[email protected]944b62f32012-09-27 02:20:463109 default_vertex_attrib_manager_ = NULL;
[email protected]1868a342012-11-07 15:56:023110 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243111 state_.bound_array_buffer = NULL;
3112 state_.current_query = NULL;
[email protected]9d3b2e12013-10-02 01:04:343113 framebuffer_state_.bound_read_framebuffer = NULL;
3114 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243115 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413116
[email protected]cadac622013-06-11 16:46:363117 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513118 DCHECK(offscreen_target_color_texture_);
3119 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3120 offscreen_saved_color_texture_->id());
3121 offscreen_saved_color_texture_->Invalidate();
3122 offscreen_saved_color_texture_info_ = NULL;
3123 }
[email protected]eadc96792010-10-27 19:39:393124 if (have_context) {
[email protected]c322e882012-05-23 18:06:183125 if (copy_texture_CHROMIUM_.get()) {
3126 copy_texture_CHROMIUM_->Destroy();
3127 copy_texture_CHROMIUM_.reset();
3128 }
[email protected]43410e92012-04-20 17:06:283129
[email protected]7cd76fd2013-06-02 21:11:113130 if (state_.current_program.get()) {
3131 program_manager()->UnuseProgram(shader_manager(),
3132 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143133 }
3134
[email protected]b1122982010-05-17 23:04:243135 if (attrib_0_buffer_id_) {
3136 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3137 }
[email protected]8fbedc02010-11-18 18:43:403138 if (fixed_attrib_buffer_id_) {
3139 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3140 }
[email protected]b1122982010-05-17 23:04:243141
[email protected]4a4c18b2013-09-13 22:50:103142 if (validation_texture_) {
3143 glDeleteTextures(1, &validation_texture_);
3144 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3145 glDeleteFramebuffersEXT(1, &validation_fbo_);
3146 }
3147
[email protected]97872062010-11-03 19:07:053148 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543149 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053150 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543151 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053152 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023153 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053154 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153155 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053156 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153157 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053158 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023159 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053160 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543161 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273162 if (offscreen_resolved_frame_buffer_.get())
3163 offscreen_resolved_frame_buffer_->Destroy();
3164 if (offscreen_resolved_color_texture_.get())
3165 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053166 } else {
3167 if (offscreen_target_frame_buffer_.get())
3168 offscreen_target_frame_buffer_->Invalidate();
3169 if (offscreen_target_color_texture_.get())
3170 offscreen_target_color_texture_->Invalidate();
3171 if (offscreen_target_color_render_buffer_.get())
3172 offscreen_target_color_render_buffer_->Invalidate();
3173 if (offscreen_target_depth_render_buffer_.get())
3174 offscreen_target_depth_render_buffer_->Invalidate();
3175 if (offscreen_target_stencil_render_buffer_.get())
3176 offscreen_target_stencil_render_buffer_->Invalidate();
3177 if (offscreen_saved_frame_buffer_.get())
3178 offscreen_saved_frame_buffer_->Invalidate();
3179 if (offscreen_saved_color_texture_.get())
3180 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273181 if (offscreen_resolved_frame_buffer_.get())
3182 offscreen_resolved_frame_buffer_->Invalidate();
3183 if (offscreen_resolved_color_texture_.get())
3184 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023185 }
[email protected]83a52d032013-07-24 10:30:373186
3187 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3188 // Otherwise, we can leak objects. http://crbug.com/258772.
3189 // state_.current_program must be reset before group_ is reset because
3190 // the later deletes the ProgramManager object that referred by
3191 // state_.current_program object.
3192 state_.current_program = NULL;
3193
[email protected]43410e92012-04-20 17:06:283194 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053195
[email protected]882ba1e22012-03-08 19:02:533196 if (query_manager_.get()) {
3197 query_manager_->Destroy(have_context);
3198 query_manager_.reset();
3199 }
3200
[email protected]944b62f32012-09-27 02:20:463201 if (vertex_array_manager_ .get()) {
3202 vertex_array_manager_->Destroy(have_context);
3203 vertex_array_manager_.reset();
3204 }
3205
[email protected]97872062010-11-03 19:07:053206 offscreen_target_frame_buffer_.reset();
3207 offscreen_target_color_texture_.reset();
3208 offscreen_target_color_render_buffer_.reset();
3209 offscreen_target_depth_render_buffer_.reset();
3210 offscreen_target_stencil_render_buffer_.reset();
3211 offscreen_saved_frame_buffer_.reset();
3212 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273213 offscreen_resolved_frame_buffer_.reset();
3214 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463215
[email protected]85a4ac22013-05-31 01:58:473216 // Should destroy the transfer manager before the texture manager held
3217 // by the context group.
3218 async_pixel_transfer_manager_.reset();
3219
[email protected]91c94eb2013-10-22 10:32:543220 framebuffer_manager()->RemoveObserver(this);
3221
[email protected]7cd76fd2013-06-02 21:11:113222 if (group_.get()) {
[email protected]2d9d3b92013-01-18 01:07:233223 group_->Destroy(this, have_context);
3224 group_ = NULL;
3225 }
3226
3227 if (context_.get()) {
3228 context_->ReleaseCurrent(NULL);
3229 context_ = NULL;
3230 }
3231
[email protected]e51bdf32011-11-23 22:21:463232#if defined(OS_MACOSX)
3233 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3234 it != texture_to_io_surface_map_.end(); ++it) {
3235 CFRelease(it->second);
3236 }
3237 texture_to_io_surface_map_.clear();
3238#endif
[email protected]96449d2c2009-11-25 00:01:323239}
3240
[email protected]63c9b052012-05-17 18:27:383241void GLES2DecoderImpl::SetSurface(
3242 const scoped_refptr<gfx::GLSurface>& surface) {
3243 DCHECK(context_->IsCurrent(NULL));
3244 DCHECK(surface_.get());
3245 surface_ = surface;
3246 RestoreCurrentFramebufferBindings();
3247}
3248
[email protected]2ad674132013-06-05 07:48:513249bool GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
[email protected]9a5afa432011-07-22 18:16:393250 if (!offscreen_saved_color_texture_.get())
3251 return false;
[email protected]2ad674132013-06-05 07:48:513252 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243253 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073254 offscreen_saved_color_texture_info_ = TextureRef::Create(
3255 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513256 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3257 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393258 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243259 }
[email protected]2ad674132013-06-05 07:48:513260 gpu::gles2::MailboxName name;
3261 memcpy(name.key, mailbox.name, sizeof(mailbox.name));
3262 return mailbox_manager()->ProduceTexture(
3263 GL_TEXTURE_2D, name, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243264}
3265
[email protected]260ddc4e2012-06-28 00:01:533266size_t GLES2DecoderImpl::GetBackbufferMemoryTotal() {
[email protected]1078f912011-12-23 13:12:143267 size_t total = 0;
3268 if (offscreen_target_frame_buffer_.get()) {
3269 if (offscreen_target_color_texture_.get()) {
3270 total += offscreen_target_color_texture_->estimated_size();
3271 }
3272 if (offscreen_target_color_render_buffer_.get()) {
3273 total += offscreen_target_color_render_buffer_->estimated_size();
3274 }
3275 if (offscreen_target_depth_render_buffer_.get()) {
3276 total += offscreen_target_depth_render_buffer_->estimated_size();
3277 }
3278 if (offscreen_target_stencil_render_buffer_.get()) {
3279 total += offscreen_target_stencil_render_buffer_->estimated_size();
3280 }
3281 if (offscreen_saved_color_texture_.get()) {
3282 total += offscreen_saved_color_texture_->estimated_size();
3283 }
3284 if (offscreen_resolved_color_texture_.get()) {
3285 total += offscreen_resolved_color_texture_->estimated_size();
3286 }
3287 } else {
3288 gfx::Size size = surface_->GetSize();
3289 total += size.width() * size.height() *
3290 GLES2Util::RenderbufferBytesPerPixel(back_buffer_color_format_);
3291 }
[email protected]260ddc4e2012-06-28 00:01:533292 return total;
[email protected]1078f912011-12-23 13:12:143293}
3294
[email protected]799b4b22011-08-22 17:09:593295bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3296 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3297 if (!is_offscreen) {
3298 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3299 << " with an onscreen framebuffer.";
3300 return false;
3301 }
3302
3303 if (offscreen_size_ == size)
3304 return true;
3305
3306 offscreen_size_ = size;
3307 int w = offscreen_size_.width();
3308 int h = offscreen_size_.height();
3309 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3310 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3311 << "to allocate storage due to excessive dimensions.";
3312 return false;
3313 }
3314
3315 // Reallocate the offscreen target buffers.
3316 DCHECK(offscreen_target_color_format_);
3317 if (IsOffscreenBufferMultisampled()) {
3318 if (!offscreen_target_color_render_buffer_->AllocateStorage(
3319 offscreen_size_, offscreen_target_color_format_,
3320 offscreen_target_samples_)) {
3321 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3322 << "to allocate storage for offscreen target color buffer.";
3323 return false;
3324 }
3325 } else {
3326 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093327 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593328 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3329 << "to allocate storage for offscreen target color texture.";
3330 return false;
3331 }
3332 }
3333 if (offscreen_target_depth_format_ &&
3334 !offscreen_target_depth_render_buffer_->AllocateStorage(
3335 offscreen_size_, offscreen_target_depth_format_,
3336 offscreen_target_samples_)) {
3337 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3338 << "to allocate storage for offscreen target depth buffer.";
3339 return false;
3340 }
3341 if (offscreen_target_stencil_format_ &&
3342 !offscreen_target_stencil_render_buffer_->AllocateStorage(
3343 offscreen_size_, offscreen_target_stencil_format_,
3344 offscreen_target_samples_)) {
3345 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3346 << "to allocate storage for offscreen target stencil buffer.";
3347 return false;
3348 }
3349
3350 // Attach the offscreen target buffers to the target frame buffer.
3351 if (IsOffscreenBufferMultisampled()) {
3352 offscreen_target_frame_buffer_->AttachRenderBuffer(
3353 GL_COLOR_ATTACHMENT0,
3354 offscreen_target_color_render_buffer_.get());
3355 } else {
3356 offscreen_target_frame_buffer_->AttachRenderTexture(
3357 offscreen_target_color_texture_.get());
3358 }
3359 if (offscreen_target_depth_format_) {
3360 offscreen_target_frame_buffer_->AttachRenderBuffer(
3361 GL_DEPTH_ATTACHMENT,
3362 offscreen_target_depth_render_buffer_.get());
3363 }
3364 const bool packed_depth_stencil =
3365 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3366 if (packed_depth_stencil) {
3367 offscreen_target_frame_buffer_->AttachRenderBuffer(
3368 GL_STENCIL_ATTACHMENT,
3369 offscreen_target_depth_render_buffer_.get());
3370 } else if (offscreen_target_stencil_format_) {
3371 offscreen_target_frame_buffer_->AttachRenderBuffer(
3372 GL_STENCIL_ATTACHMENT,
3373 offscreen_target_stencil_render_buffer_.get());
3374 }
3375
3376 if (offscreen_target_frame_buffer_->CheckStatus() !=
3377 GL_FRAMEBUFFER_COMPLETE) {
3378 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3379 << "because offscreen FBO was incomplete.";
3380 return false;
3381 }
3382
3383 // Clear the target frame buffer.
3384 {
3385 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3386 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3387 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3388 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3389 glClearStencil(0);
3390 glStencilMaskSeparate(GL_FRONT, -1);
3391 glStencilMaskSeparate(GL_BACK, -1);
3392 glClearDepth(0);
3393 glDepthMask(GL_TRUE);
3394 glDisable(GL_SCISSOR_TEST);
3395 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3396 RestoreClearState();
3397 }
[email protected]d85ef76d2011-09-08 22:21:433398
3399 // Destroy the offscreen resolved framebuffers.
3400 if (offscreen_resolved_frame_buffer_.get())
3401 offscreen_resolved_frame_buffer_->Destroy();
3402 if (offscreen_resolved_color_texture_.get())
3403 offscreen_resolved_color_texture_->Destroy();
3404 offscreen_resolved_color_texture_.reset();
3405 offscreen_resolved_frame_buffer_.reset();
3406
[email protected]799b4b22011-08-22 17:09:593407 return true;
[email protected]6217d392010-03-25 22:08:353408}
3409
[email protected]799b4b22011-08-22 17:09:593410error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:353411 uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) {
[email protected]09e17272012-11-30 10:30:443412 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023413 return error::kDeferCommandUntilLater;
3414
[email protected]799b4b22011-08-22 17:09:593415 GLuint width = static_cast<GLuint>(c.width);
3416 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073417 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593418 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413419
3420 width = std::max(1U, width);
3421 height = std::max(1U, height);
3422
[email protected]a0d989162011-11-22 13:15:073423#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3424 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003425 // Make sure that we are done drawing to the back buffer before resizing.
3426 glFinish();
3427#endif
[email protected]799b4b22011-08-22 17:09:593428 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3429 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493430 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3431 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3432 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593433 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493434 }
[email protected]7ff86b92010-11-25 17:50:003435 }
[email protected]799b4b22011-08-22 17:09:593436
[email protected]9d37f062011-11-22 01:24:523437 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073438 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443439 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493440 if (!context_->IsCurrent(surface_.get())) {
3441 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3442 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053443 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493444 }
[email protected]658f7562011-09-09 05:24:053445 }
[email protected]799b4b22011-08-22 17:09:593446
3447 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393448}
3449
[email protected]96449d2c2009-11-25 00:01:323450const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3451 if (command_id > kStartPoint && command_id < kNumCommands) {
3452 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3453 }
3454 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3455}
3456
3457// Decode command with its arguments, and call the corresponding GL function.
3458// Note: args is a pointer to the command buffer. As such, it could be changed
3459// by a (malicious) client at any time, so if validation has to happen, it
3460// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143461error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323462 unsigned int command,
3463 unsigned int arg_count,
3464 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143465 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263466 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003467 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
3468 // LOG(INFO), tried VLOG(1), no luck.
[email protected]1d82e822013-04-10 21:32:323469 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" << "cmd: "
[email protected]d2a0e1a2012-08-12 02:25:013470 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193471 }
[email protected]96449d2c2009-11-25 00:01:323472 unsigned int command_index = command - kStartPoint - 1;
3473 if (command_index < arraysize(g_command_info)) {
3474 const CommandInfo& info = g_command_info[command_index];
3475 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3476 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3477 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]b9849abf2009-11-25 19:13:193478 uint32 immediate_data_size =
3479 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323480 switch (command) {
3481 #define GLES2_CMD_OP(name) \
[email protected]ed9f9cd2013-02-27 21:12:353482 case cmds::name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193483 result = Handle ## name( \
3484 immediate_data_size, \
[email protected]ed9f9cd2013-02-27 21:12:353485 *static_cast<const gles2::cmds::name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193486 break; \
[email protected]96449d2c2009-11-25 00:01:323487
3488 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323489 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383490 }
3491 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303492 GLenum error;
3493 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]1d82e822013-04-10 21:32:323494 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003495 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3496 << GetCommandName(command);
[email protected]ab09b612013-03-11 22:11:513497 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193498 }
[email protected]96449d2c2009-11-25 00:01:323499 }
3500 } else {
[email protected]f7a64ee2010-02-01 22:24:143501 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323502 }
[email protected]b9849abf2009-11-25 19:13:193503 } else {
3504 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323505 }
[email protected]a3a93e7b2010-08-28 00:48:563506 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3507 result = current_decoder_error_;
3508 current_decoder_error_ = error::kNoError;
3509 }
[email protected]b9849abf2009-11-25 19:13:193510 return result;
[email protected]96449d2c2009-11-25 00:01:323511}
3512
[email protected]ed9f9cd2013-02-27 21:12:353513void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3514 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503515}
3516
[email protected]ae51d192010-04-27 00:48:033517bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353518 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033519 return false;
3520 }
[email protected]96449d2c2009-11-25 00:01:323521 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033522 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353523 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323524 }
[email protected]ae51d192010-04-27 00:48:033525 return true;
[email protected]96449d2c2009-11-25 00:01:323526}
3527
[email protected]ae51d192010-04-27 00:48:033528bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353529 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033530 return false;
[email protected]96449d2c2009-11-25 00:01:323531 }
[email protected]ae51d192010-04-27 00:48:033532 GLuint service_id = glCreateShader(type);
3533 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353534 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033535 }
3536 return true;
[email protected]96449d2c2009-11-25 00:01:323537}
3538
[email protected]882ba1e22012-03-08 19:02:533539void GLES2DecoderImpl::DoFinish() {
3540 glFinish();
[email protected]5a36dc132013-07-23 23:17:553541 ProcessPendingReadPixels();
[email protected]22e3f552012-03-13 01:54:193542 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533543}
3544
3545void GLES2DecoderImpl::DoFlush() {
3546 glFlush();
[email protected]22e3f552012-03-13 01:54:193547 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533548}
3549
[email protected]3916c97e2010-02-25 03:20:503550void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453551 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023552 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513553 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533554 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503555 return;
3556 }
[email protected]e259eb412012-10-13 05:47:243557 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453558 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503559}
3560
[email protected]051b1372010-04-12 02:42:083561void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073562 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083563 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033564 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073565 buffer = GetBuffer(client_id);
3566 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353567 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153568 LOG(ERROR) << "glBindBuffer: id not generated by glGenBuffers";
3569 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353570 return;
3571 }
3572
[email protected]b10492f2013-03-08 05:24:073573 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033574 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353575 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073576 buffer = GetBuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573577 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103578 group_->GetIdAllocator(id_namespaces::kBuffers);
3579 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033580 }
[email protected]051b1372010-04-12 02:42:083581 }
[email protected]b10492f2013-03-08 05:24:073582 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3583 if (buffer) {
3584 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513585 LOCAL_SET_GL_ERROR(
3586 GL_INVALID_OPERATION,
3587 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473588 return;
3589 }
[email protected]b10492f2013-03-08 05:24:073590 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473591 }
[email protected]96449d2c2009-11-25 00:01:323592 switch (target) {
3593 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073594 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323595 break;
3596 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073597 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323598 break;
3599 default:
[email protected]a93bb842010-02-16 23:03:473600 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323601 break;
3602 }
[email protected]051b1372010-04-12 02:42:083603 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323604}
3605
[email protected]f3b191b2013-06-19 03:43:543606bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
3607 bool all_draw_buffers) {
3608 Framebuffer* framebuffer =
3609 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3610 if (!all_draw_buffers || !framebuffer) {
3611 return (GLES2Util::GetChannelsForFormat(
3612 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3613 }
3614 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:463615}
3616
3617bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353618 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453619 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203620 if (framebuffer) {
3621 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463622 }
3623 if (offscreen_target_frame_buffer_.get()) {
3624 return offscreen_target_depth_format_ != 0;
3625 }
3626 return back_buffer_has_depth_;
3627}
3628
3629bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353630 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453631 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203632 if (framebuffer) {
3633 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463634 }
3635 if (offscreen_target_frame_buffer_.get()) {
3636 return offscreen_target_stencil_format_ != 0 ||
3637 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3638 }
3639 return back_buffer_has_stencil_;
3640}
3641
3642void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:443643 if (framebuffer_state_.clear_state_dirty) {
[email protected]297ca1c2011-06-20 23:08:463644 glColorMask(
[email protected]e259eb412012-10-13 05:47:243645 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
3646 state_.color_mask_alpha &&
[email protected]f3b191b2013-06-19 03:43:543647 BoundFramebufferHasColorAttachmentWithAlpha(true));
[email protected]297ca1c2011-06-20 23:08:463648 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]e259eb412012-10-13 05:47:243649 glDepthMask(state_.depth_mask && have_depth);
[email protected]f731b9462012-10-30 00:35:223650 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
[email protected]297ca1c2011-06-20 23:08:463651 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]e259eb412012-10-13 05:47:243652 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423653 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]e259eb412012-10-13 05:47:243654 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423655 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]f731b9462012-10-30 00:35:223656 EnableDisable(
3657 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3658 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
3659 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
3660 EnableDisable(GL_BLEND, state_.enable_flags.blend);
[email protected]c986af502013-08-14 01:04:443661 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:463662 }
3663}
3664
[email protected]1868a342012-11-07 15:56:023665GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:113666 return (offscreen_target_frame_buffer_.get())
3667 ? offscreen_target_frame_buffer_->id()
3668 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:023669}
3670
3671void GLES2DecoderImpl::RestoreState() const {
[email protected]962bfbe72013-05-24 11:16:143672 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
3673 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:063674 // Restore the Framebuffer first because of bugs in Intel drivers.
3675 // Intel drivers incorrectly clip the viewport settings to
3676 // the size of the current framebuffer object.
3677 RestoreFramebufferBindings();
3678 state_.RestoreState();
3679}
3680
3681void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:343682 GLuint service_id =
3683 framebuffer_state_.bound_draw_framebuffer.get()
3684 ? framebuffer_state_.bound_draw_framebuffer->service_id()
3685 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063686 if (!features().chromium_framebuffer_multisample) {
3687 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
3688 } else {
3689 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:343690 service_id = framebuffer_state_.bound_read_framebuffer.get()
3691 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:113692 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063693 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
3694 }
[email protected]70d34263c2013-01-09 00:27:453695 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:063696}
3697
3698void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:103699 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
3700 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:253701 GLenum target = texture->target();
3702 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:063703 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253704 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:063705 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253706 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:063707 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253708 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:063709 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253710 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:063711 RestoreTextureUnitBindings(state_.active_texture_unit);
3712 }
[email protected]70d34263c2013-01-09 00:27:453713}
3714
3715void GLES2DecoderImpl::OnFboChanged() const {
3716 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:513717 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
3718}
3719
3720// Called after the FBO is checked for completeness.
3721void GLES2DecoderImpl::OnUseFramebuffer() const {
3722 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
3723 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:323724 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:513725 glScissor(state_.scissor_x,
3726 state_.scissor_y,
3727 state_.scissor_width,
3728 state_.scissor_height);
3729
3730 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
3731 // it's unclear how this bug works.
3732 glFlush();
3733 }
[email protected]b177ae22011-11-01 03:29:113734}
3735
[email protected]051b1372010-04-12 02:42:083736void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:063737 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:083738 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033739 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:063740 framebuffer = GetFramebuffer(client_id);
3741 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:353742 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153743 LOG(ERROR)
3744 << "glBindFramebuffer: id not generated by glGenFramebuffers";
3745 current_decoder_error_ = error::kGenericError;
3746 return;
[email protected]bf5a8d132011-08-16 08:39:353747 }
3748
[email protected]4d8f0dd2013-03-09 14:37:063749 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:033750 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353751 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:063752 framebuffer = GetFramebuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573753 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103754 group_->GetIdAllocator(id_namespaces::kFramebuffers);
3755 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033756 } else {
[email protected]4d8f0dd2013-03-09 14:37:063757 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:083758 }
[email protected]4d8f0dd2013-03-09 14:37:063759 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083760 }
[email protected]4d8f0dd2013-03-09 14:37:063761 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:303762
3763 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:343764 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303765 }
3766 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:343767 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303768 }
[email protected]6217d392010-03-25 22:08:353769
[email protected]c986af502013-08-14 01:04:443770 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463771
[email protected]b177ae22011-11-01 03:29:113772 // If we are rendering to the backbuffer get the FBO id for any simulated
3773 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:063774 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:113775 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:463776 }
[email protected]6217d392010-03-25 22:08:353777
[email protected]051b1372010-04-12 02:42:083778 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:453779 OnFboChanged();
[email protected]86093972010-03-11 00:13:563780}
3781
[email protected]051b1372010-04-12 02:42:083782void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:273783 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:083784 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033785 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:273786 renderbuffer = GetRenderbuffer(client_id);
3787 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:353788 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153789 LOG(ERROR)
3790 << "glBindRenderbuffer: id not generated by glGenRenderbuffers";
3791 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353792 return;
3793 }
3794
[email protected]ee2a79c32013-03-10 03:50:273795 // It's a new id so make a renderbuffer renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:033796 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353797 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:273798 renderbuffer = GetRenderbuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573799 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103800 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
3801 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033802 } else {
[email protected]ee2a79c32013-03-10 03:50:273803 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:083804 }
[email protected]ee2a79c32013-03-10 03:50:273805 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083806 }
[email protected]ee2a79c32013-03-10 03:50:273807 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenerbuffer");
3808 state_.bound_renderbuffer = renderbuffer;
[email protected]051b1372010-04-12 02:42:083809 glBindRenderbufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563810}
3811
[email protected]051b1372010-04-12 02:42:083812void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:493813 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:083814 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033815 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:493816 texture_ref = GetTexture(client_id);
3817 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:353818 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153819 LOG(ERROR) << "glBindTexture: id not generated by glGenTextures";
3820 current_decoder_error_ = error::kGenericError;
3821 return;
[email protected]bf5a8d132011-08-16 08:39:353822 }
3823
[email protected]02965c22013-03-09 02:40:073824 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:033825 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:413826 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:353827 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:493828 texture_ref = GetTexture(client_id);
[email protected]3b1ecc262011-08-03 22:49:573829 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103830 group_->GetIdAllocator(id_namespaces::kTextures);
3831 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033832 }
3833 } else {
[email protected]370eaf12013-05-18 09:19:493834 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:083835 }
[email protected]370eaf12013-05-18 09:19:493836 Texture* texture = texture_ref->texture();
[email protected]ae51d192010-04-27 00:48:033837
[email protected]1958e0e2010-04-22 05:17:153838 // Check the texture exists
3839 // Check that we are not trying to bind it to a different target.
[email protected]02965c22013-03-09 02:40:073840 if (texture->target() != 0 && texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:513841 LOCAL_SET_GL_ERROR(
3842 GL_INVALID_OPERATION,
3843 "glBindTexture", "texture bound to more than 1 target.");
[email protected]1958e0e2010-04-22 05:17:153844 return;
3845 }
[email protected]02965c22013-03-09 02:40:073846 if (texture->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:513847 LOCAL_SET_GL_ERROR(
3848 GL_INVALID_OPERATION,
3849 "glBindTexture", "illegal target for stream texture.");
[email protected]b0af4f52011-09-28 22:04:423850 return;
3851 }
[email protected]02965c22013-03-09 02:40:073852 LogClientServiceForInfo(texture, client_id, "glBindTexture");
3853 if (texture->target() == 0) {
[email protected]370eaf12013-05-18 09:19:493854 texture_manager()->SetTarget(texture_ref, target);
[email protected]a93bb842010-02-16 23:03:473855 }
[email protected]02965c22013-03-09 02:40:073856 glBindTexture(target, texture->service_id());
[email protected]32145a92012-12-17 09:01:593857
[email protected]e259eb412012-10-13 05:47:243858 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:503859 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:473860 switch (target) {
3861 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:493862 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:473863 break;
3864 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:493865 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:473866 break;
[email protected]61eeb33f2011-07-26 15:30:313867 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:493868 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:313869 break;
[email protected]e51bdf32011-11-23 22:21:463870 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:493871 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:463872 break;
[email protected]a93bb842010-02-16 23:03:473873 default:
3874 NOTREACHED(); // Validation should prevent us getting here.
3875 break;
3876 }
3877}
3878
[email protected]07f54fcc2009-12-22 02:46:303879void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243880 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:123881 if (index != 0 ||
3882 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:243883 glDisableVertexAttribArray(index);
3884 }
[email protected]07f54fcc2009-12-22 02:46:303885 } else {
[email protected]ab09b612013-03-11 22:11:513886 LOCAL_SET_GL_ERROR(
3887 GL_INVALID_VALUE,
3888 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303889 }
3890}
3891
[email protected]60f22d32012-12-12 00:31:583892void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
3893 GLsizei numAttachments,
3894 const GLenum* attachments) {
[email protected]680aa412013-10-31 18:08:013895 if (!features().ext_discard_framebuffer) {
3896 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
3897 "glDiscardFramebufferEXT",
3898 "function not available");
3899 return;
3900 }
3901
[email protected]ed9f9cd2013-02-27 21:12:353902 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:583903 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
3904
3905 // Validates the attachments. If one of them fails
3906 // the whole command fails.
3907 for (GLsizei i = 0; i < numAttachments; ++i) {
3908 if ((framebuffer &&
3909 !validators_->attachment.IsValid(attachments[i])) ||
3910 (!framebuffer &&
3911 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:513912 LOCAL_SET_GL_ERROR_INVALID_ENUM(
3913 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:583914 return;
3915 }
3916 }
3917
3918 // Marks each one of them as not cleared
3919 for (GLsizei i = 0; i < numAttachments; ++i) {
3920 if (framebuffer) {
3921 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
3922 texture_manager(),
3923 attachments[i],
3924 false);
3925 } else {
3926 switch (attachments[i]) {
3927 case GL_COLOR_EXT:
3928 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
3929 break;
3930 case GL_DEPTH_EXT:
3931 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
3932 case GL_STENCIL_EXT:
3933 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
3934 break;
3935 default:
3936 NOTREACHED();
3937 break;
3938 }
3939 }
3940 }
3941
[email protected]d49c5402013-09-11 15:39:023942 // If the default framebuffer is bound but we are still rendering to an
3943 // FBO, translate attachment names that refer to default framebuffer
3944 // channels to corresponding framebuffer attachments.
3945 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
3946 for (GLsizei i = 0; i < numAttachments; ++i) {
3947 GLenum attachment = attachments[i];
3948 if (!framebuffer && GetBackbufferServiceId()) {
3949 switch (attachment) {
3950 case GL_COLOR_EXT:
3951 attachment = GL_COLOR_ATTACHMENT0;
3952 break;
3953 case GL_DEPTH_EXT:
3954 attachment = GL_DEPTH_ATTACHMENT;
3955 break;
3956 case GL_STENCIL_EXT:
3957 attachment = GL_STENCIL_ATTACHMENT;
3958 break;
3959 default:
3960 NOTREACHED();
3961 return;
3962 }
3963 }
3964 translated_attachments[i] = attachment;
3965 }
3966
3967 glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get());
[email protected]60f22d32012-12-12 00:31:583968}
3969
[email protected]07f54fcc2009-12-22 02:46:303970void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:243971 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:303972 glEnableVertexAttribArray(index);
3973 } else {
[email protected]ab09b612013-03-11 22:11:513974 LOCAL_SET_GL_ERROR(
3975 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:303976 }
3977}
3978
[email protected]a93bb842010-02-16 23:03:473979void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:443980 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3981 &state_, target);
[email protected]370eaf12013-05-18 09:19:493982 if (!texture_ref ||
3983 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:513984 LOCAL_SET_GL_ERROR(
3985 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:473986 return;
3987 }
[email protected]38c0a972012-05-12 00:48:023988
[email protected]12d95352012-12-14 07:23:543989 if (target == GL_TEXTURE_CUBE_MAP) {
3990 for (int i = 0; i < 6; ++i) {
3991 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:493992 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:513993 LOCAL_SET_GL_ERROR(
3994 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:543995 return;
3996 }
3997 }
3998 } else {
[email protected]370eaf12013-05-18 09:19:493999 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514000 LOCAL_SET_GL_ERROR(
4001 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544002 return;
4003 }
[email protected]7687479c2012-05-14 23:54:044004 }
4005
[email protected]ab09b612013-03-11 22:11:514006 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194007 // Workaround for Mac driver bug. In the large scheme of things setting
4008 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564009 // hit so there's probably no need to make this conditional. The bug appears
4010 // to be that if the filtering mode is set to something that doesn't require
4011 // mipmaps for rendering, or is never set to something other than the default,
4012 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154013 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194014 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4015 }
[email protected]a93bb842010-02-16 23:03:474016 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154017 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494018 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4019 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194020 }
[email protected]ab09b612013-03-11 22:11:514021 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024022 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494023 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024024 }
[email protected]a93bb842010-02-16 23:03:474025}
4026
[email protected]b273e432010-04-12 17:23:584027bool GLES2DecoderImpl::GetHelper(
4028 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584029 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154030 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4031 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434032 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4033 *num_written = 1;
4034 if (params) {
4035 *params = GL_RGBA; // We don't support other formats.
4036 }
4037 return true;
4038 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4039 *num_written = 1;
4040 if (params) {
4041 *params = GL_UNSIGNED_BYTE; // We don't support other types.
4042 }
4043 return true;
4044 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4045 *num_written = 1;
4046 if (params) {
4047 *params = group_->max_fragment_uniform_vectors();
4048 }
4049 return true;
4050 case GL_MAX_VARYING_VECTORS:
4051 *num_written = 1;
4052 if (params) {
4053 *params = group_->max_varying_vectors();
4054 }
4055 return true;
4056 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4057 *num_written = 1;
4058 if (params) {
4059 *params = group_->max_vertex_uniform_vectors();
4060 }
4061 return true;
[email protected]4e8a5b122010-05-08 22:00:104062 }
[email protected]5cb735d2011-10-13 01:37:234063 }
4064 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244065 case GL_MAX_VIEWPORT_DIMS:
4066 if (offscreen_target_frame_buffer_.get()) {
4067 *num_written = 2;
4068 if (params) {
4069 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4070 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4071 }
4072 return true;
4073 }
[email protected]5cb735d2011-10-13 01:37:234074 return false;
[email protected]84afefa2011-10-19 21:45:534075 case GL_MAX_SAMPLES:
4076 *num_written = 1;
4077 if (params) {
4078 params[0] = renderbuffer_manager()->max_samples();
4079 }
4080 return true;
4081 case GL_MAX_RENDERBUFFER_SIZE:
4082 *num_written = 1;
4083 if (params) {
4084 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4085 }
4086 return true;
[email protected]5cb735d2011-10-13 01:37:234087 case GL_MAX_TEXTURE_SIZE:
4088 *num_written = 1;
4089 if (params) {
4090 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4091 }
4092 return true;
4093 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4094 *num_written = 1;
4095 if (params) {
4096 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4097 }
4098 return true;
[email protected]2f143d482013-03-14 18:04:494099 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4100 *num_written = 1;
4101 if (params) {
4102 params[0] = group_->max_color_attachments();
4103 }
4104 return true;
4105 case GL_MAX_DRAW_BUFFERS_ARB:
4106 *num_written = 1;
4107 if (params) {
4108 params[0] = group_->max_draw_buffers();
4109 }
4110 return true;
[email protected]297ca1c2011-06-20 23:08:464111 case GL_ALPHA_BITS:
4112 *num_written = 1;
4113 if (params) {
4114 GLint v = 0;
4115 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544116 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464117 }
4118 return true;
4119 case GL_DEPTH_BITS:
4120 *num_written = 1;
4121 if (params) {
4122 GLint v = 0;
4123 glGetIntegerv(GL_DEPTH_BITS, &v);
4124 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4125 }
4126 return true;
4127 case GL_STENCIL_BITS:
4128 *num_written = 1;
4129 if (params) {
4130 GLint v = 0;
4131 glGetIntegerv(GL_STENCIL_BITS, &v);
4132 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4133 }
4134 return true;
[email protected]656dcaad2010-05-07 17:18:374135 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114136 *num_written = validators_->compressed_texture_format.GetValues().size();
4137 if (params) {
4138 for (GLint ii = 0; ii < *num_written; ++ii) {
4139 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4140 }
4141 }
[email protected]656dcaad2010-05-07 17:18:374142 return true;
[email protected]b273e432010-04-12 17:23:584143 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4144 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104145 if (params) {
[email protected]302ce6d2011-07-07 23:28:114146 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104147 }
[email protected]b273e432010-04-12 17:23:584148 return true;
4149 case GL_NUM_SHADER_BINARY_FORMATS:
4150 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104151 if (params) {
[email protected]302ce6d2011-07-07 23:28:114152 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104153 }
[email protected]b273e432010-04-12 17:23:584154 return true;
4155 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114156 *num_written = validators_->shader_binary_format.GetValues().size();
4157 if (params) {
4158 for (GLint ii = 0; ii < *num_written; ++ii) {
4159 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4160 }
4161 }
4162 return true;
[email protected]b273e432010-04-12 17:23:584163 case GL_SHADER_COMPILER:
4164 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104165 if (params) {
4166 *params = GL_TRUE;
4167 }
[email protected]b273e432010-04-12 17:23:584168 return true;
[email protected]6b8cf1a2010-05-06 16:13:584169 case GL_ARRAY_BUFFER_BINDING:
4170 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104171 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114172 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104173 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244174 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104175 &client_id);
4176 *params = client_id;
4177 } else {
4178 *params = 0;
4179 }
[email protected]6b8cf1a2010-05-06 16:13:584180 }
4181 return true;
4182 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4183 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104184 if (params) {
[email protected]e259eb412012-10-13 05:47:244185 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104186 GLuint client_id = 0;
4187 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254188 state_.vertex_attrib_manager->element_array_buffer()->
4189 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104190 *params = client_id;
4191 } else {
4192 *params = 0;
4193 }
[email protected]6b8cf1a2010-05-06 16:13:584194 }
4195 return true;
4196 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304197 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584198 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104199 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354200 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454201 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204202 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104203 GLuint client_id = 0;
4204 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204205 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304206 *params = client_id;
4207 } else {
4208 *params = 0;
4209 }
4210 }
4211 return true;
[email protected]ebfb73c2012-08-15 02:37:454212 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304213 *num_written = 1;
4214 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354215 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454216 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204217 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304218 GLuint client_id = 0;
4219 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204220 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104221 *params = client_id;
4222 } else {
4223 *params = 0;
4224 }
[email protected]6b8cf1a2010-05-06 16:13:584225 }
4226 return true;
4227 case GL_RENDERBUFFER_BINDING:
4228 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104229 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354230 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204231 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4232 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104233 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104234 } else {
4235 *params = 0;
4236 }
[email protected]6b8cf1a2010-05-06 16:13:584237 }
4238 return true;
4239 case GL_CURRENT_PROGRAM:
4240 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104241 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114242 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104243 GLuint client_id = 0;
4244 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244245 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104246 *params = client_id;
4247 } else {
4248 *params = 0;
4249 }
[email protected]6b8cf1a2010-05-06 16:13:584250 }
4251 return true;
[email protected]bf835842012-11-19 15:21:514252 case GL_VERTEX_ARRAY_BINDING_OES:
4253 *num_written = 1;
4254 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114255 if (state_.vertex_attrib_manager.get() !=
4256 default_vertex_attrib_manager_.get()) {
[email protected]bf835842012-11-19 15:21:514257 GLuint client_id = 0;
4258 vertex_array_manager_->GetClientId(
4259 state_.vertex_attrib_manager->service_id(), &client_id);
4260 *params = client_id;
4261 } else {
4262 *params = 0;
4263 }
4264 }
4265 return true;
[email protected]4e8a5b122010-05-08 22:00:104266 case GL_TEXTURE_BINDING_2D:
4267 *num_written = 1;
4268 if (params) {
[email protected]e259eb412012-10-13 05:47:244269 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114270 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104271 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584272 } else {
4273 *params = 0;
4274 }
[email protected]6b8cf1a2010-05-06 16:13:584275 }
[email protected]4e8a5b122010-05-08 22:00:104276 return true;
4277 case GL_TEXTURE_BINDING_CUBE_MAP:
4278 *num_written = 1;
4279 if (params) {
[email protected]e259eb412012-10-13 05:47:244280 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114281 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104282 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584283 } else {
4284 *params = 0;
4285 }
[email protected]6b8cf1a2010-05-06 16:13:584286 }
[email protected]4e8a5b122010-05-08 22:00:104287 return true;
[email protected]61eeb33f2011-07-26 15:30:314288 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4289 *num_written = 1;
4290 if (params) {
[email protected]e259eb412012-10-13 05:47:244291 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114292 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104293 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314294 } else {
4295 *params = 0;
4296 }
4297 }
4298 return true;
[email protected]e51bdf32011-11-23 22:21:464299 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4300 *num_written = 1;
4301 if (params) {
[email protected]e259eb412012-10-13 05:47:244302 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114303 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104304 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464305 } else {
4306 *params = 0;
4307 }
4308 }
4309 return true;
[email protected]6c75c712012-06-19 15:43:174310 case GL_UNPACK_FLIP_Y_CHROMIUM:
4311 *num_written = 1;
4312 if (params) {
4313 params[0] = unpack_flip_y_;
4314 }
4315 return true;
4316 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4317 *num_written = 1;
4318 if (params) {
4319 params[0] = unpack_premultiply_alpha_;
4320 }
4321 return true;
4322 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4323 *num_written = 1;
4324 if (params) {
4325 params[0] = unpack_unpremultiply_alpha_;
4326 }
4327 return true;
[email protected]b273e432010-04-12 17:23:584328 default:
[email protected]2f143d482013-03-14 18:04:494329 if (pname >= GL_DRAW_BUFFER0_ARB &&
4330 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4331 *num_written = 1;
4332 if (params) {
4333 Framebuffer* framebuffer =
4334 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4335 if (framebuffer) {
4336 params[0] = framebuffer->GetDrawBuffer(pname);
4337 } else { // backbuffer
4338 if (pname == GL_DRAW_BUFFER0_ARB)
4339 params[0] = group_->draw_buffer();
4340 else
4341 params[0] = GL_NONE;
4342 }
4343 }
4344 return true;
4345 }
[email protected]4e8a5b122010-05-08 22:00:104346 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534347 return false;
[email protected]b273e432010-04-12 17:23:584348 }
4349}
4350
[email protected]4e8a5b122010-05-08 22:00:104351bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4352 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264353 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534354 return true;
4355 }
[email protected]4e8a5b122010-05-08 22:00:104356 return GetHelper(pname, NULL, num_values);
4357}
4358
[email protected]7d3c36e2013-07-12 14:13:164359GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4360 if (GL_MAX_SAMPLES == pname &&
4361 features().use_img_for_multisampled_render_to_texture) {
4362 return GL_MAX_SAMPLES_IMG;
4363 }
4364 return pname;
4365}
4366
[email protected]b273e432010-04-12 17:23:584367void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4368 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104369 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534370 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554371 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264372 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534373 GetHelper(pname, values.get(), &num_written);
4374 }
[email protected]b273e432010-04-12 17:23:584375 for (GLsizei ii = 0; ii < num_written; ++ii) {
4376 params[ii] = static_cast<GLboolean>(values[ii]);
4377 }
4378 } else {
[email protected]7d3c36e2013-07-12 14:13:164379 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584380 glGetBooleanv(pname, params);
4381 }
4382}
4383
4384void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4385 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104386 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264387 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534388 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554389 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534390 GetHelper(pname, values.get(), &num_written);
4391 for (GLsizei ii = 0; ii < num_written; ++ii) {
4392 params[ii] = static_cast<GLfloat>(values[ii]);
4393 }
4394 } else {
[email protected]7d3c36e2013-07-12 14:13:164395 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534396 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584397 }
[email protected]b273e432010-04-12 17:23:584398 }
4399}
4400
4401void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4402 DCHECK(params);
4403 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264404 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534405 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:164406 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584407 glGetIntegerv(pname, params);
4408 }
4409}
4410
[email protected]a0c3e972010-04-21 00:49:134411void GLES2DecoderImpl::DoGetProgramiv(
4412 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424413 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4414 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134415 return;
4416 }
[email protected]df37b9932013-03-08 05:21:424417 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134418}
4419
[email protected]17cfbe0e2013-03-07 01:26:084420void GLES2DecoderImpl::DoGetBufferParameteriv(
4421 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:134422 // Just delegate it. Some validation is actually done before this.
4423 buffer_manager()->ValidateAndDoGetBufferParameteriv(
4424 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:084425}
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
[email protected]558847a2010-03-24 07:02:544468error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:354469 uint32 immediate_data_size, const cmds::BindAttribLocationBucket& 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 Bucket* bucket = GetBucket(c.name_bucket_id);
4473 if (!bucket || bucket->size() == 0) {
4474 return error::kInvalidArguments;
4475 }
4476 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184477 if (!bucket->GetAsString(&name_str)) {
4478 return error::kInvalidArguments;
4479 }
[email protected]258a3313f2011-10-18 20:13:574480 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544481 return error::kNoError;
4482}
4483
[email protected]2be6abf32012-06-26 00:28:334484void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424485 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334486 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514487 LOCAL_SET_GL_ERROR(
4488 GL_INVALID_VALUE,
4489 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334490 return;
4491 }
4492 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514493 LOCAL_SET_GL_ERROR(
4494 GL_INVALID_OPERATION,
4495 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334496 return;
4497 }
4498 if (location < 0 || static_cast<uint32>(location) >=
4499 (group_->max_fragment_uniform_vectors() +
4500 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514501 LOCAL_SET_GL_ERROR(
4502 GL_INVALID_VALUE,
4503 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334504 return;
4505 }
[email protected]df37b9932013-03-08 05:21:424506 Program* program = GetProgramInfoNotShader(
4507 program_id, "glBindUniformLocationCHROMIUM");
4508 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334509 return;
4510 }
[email protected]df37b9932013-03-08 05:21:424511 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514512 LOCAL_SET_GL_ERROR(
4513 GL_INVALID_VALUE,
4514 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334515 }
4516}
4517
4518error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354519 uint32 immediate_data_size, const cmds::BindUniformLocationCHROMIUM& c) {
[email protected]2be6abf32012-06-26 00:28:334520 GLuint program = static_cast<GLuint>(c.program);
4521 GLint location = static_cast<GLint>(c.location);
4522 uint32 name_size = c.data_size;
4523 const char* name = GetSharedMemoryAs<const char*>(
4524 c.name_shm_id, c.name_shm_offset, name_size);
4525 if (name == NULL) {
4526 return error::kOutOfBounds;
4527 }
4528 String name_str(name, name_size);
4529 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4530 return error::kNoError;
4531}
4532
[email protected]2be6abf32012-06-26 00:28:334533error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4534 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354535 const cmds::BindUniformLocationCHROMIUMBucket& c) {
[email protected]2be6abf32012-06-26 00:28:334536 GLuint program = static_cast<GLuint>(c.program);
4537 GLint location = static_cast<GLint>(c.location);
4538 Bucket* bucket = GetBucket(c.name_bucket_id);
4539 if (!bucket || bucket->size() == 0) {
4540 return error::kInvalidArguments;
4541 }
4542 std::string name_str;
4543 if (!bucket->GetAsString(&name_str)) {
4544 return error::kInvalidArguments;
4545 }
4546 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4547 return error::kNoError;
4548}
4549
[email protected]f7a64ee2010-02-01 22:24:144550error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ed9f9cd2013-02-27 21:12:354551 uint32 immediate_data_size, const cmds::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034552 GLuint client_id = c.shader;
4553 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424554 Shader* shader = GetShader(client_id);
4555 if (shader) {
4556 if (!shader->IsDeleted()) {
4557 glDeleteShader(shader->service_id());
4558 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144559 }
[email protected]ae51d192010-04-27 00:48:034560 } else {
[email protected]ab09b612013-03-11 22:11:514561 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034562 }
[email protected]96449d2c2009-11-25 00:01:324563 }
[email protected]f7a64ee2010-02-01 22:24:144564 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324565}
4566
[email protected]f7a64ee2010-02-01 22:24:144567error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ed9f9cd2013-02-27 21:12:354568 uint32 immediate_data_size, const cmds::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034569 GLuint client_id = c.program;
4570 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424571 Program* program = GetProgram(client_id);
4572 if (program) {
4573 if (!program->IsDeleted()) {
4574 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144575 }
[email protected]ae51d192010-04-27 00:48:034576 } else {
[email protected]ab09b612013-03-11 22:11:514577 LOCAL_SET_GL_ERROR(
4578 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034579 }
[email protected]96449d2c2009-11-25 00:01:324580 }
[email protected]f7a64ee2010-02-01 22:24:144581 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324582}
4583
[email protected]269200b12010-11-18 22:53:064584void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104585 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574586 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104587 for (GLsizei ii = 0; ii < n; ++ii) {
4588 id_allocator->FreeID(ids[ii]);
4589 }
4590}
4591
[email protected]269200b12010-11-18 22:53:064592error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354593 uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104594 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4595 GLsizei n = static_cast<GLsizei>(c.n);
4596 uint32 data_size;
4597 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4598 return error::kOutOfBounds;
4599 }
4600 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4601 c.ids_shm_id, c.ids_shm_offset, data_size);
4602 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514603 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104604 return error::kNoError;
4605 }
4606 if (ids == NULL) {
4607 return error::kOutOfBounds;
4608 }
[email protected]269200b12010-11-18 22:53:064609 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104610 return error::kNoError;
4611}
4612
[email protected]269200b12010-11-18 22:53:064613void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104614 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574615 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104616 if (id_offset == 0) {
4617 for (GLsizei ii = 0; ii < n; ++ii) {
4618 ids[ii] = id_allocator->AllocateID();
4619 }
4620 } else {
4621 for (GLsizei ii = 0; ii < n; ++ii) {
4622 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4623 id_offset = ids[ii] + 1;
4624 }
4625 }
4626}
4627
[email protected]269200b12010-11-18 22:53:064628error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354629 uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104630 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4631 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4632 GLsizei n = static_cast<GLsizei>(c.n);
4633 uint32 data_size;
4634 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4635 return error::kOutOfBounds;
4636 }
4637 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4638 c.ids_shm_id, c.ids_shm_offset, data_size);
4639 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514640 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104641 return error::kNoError;
4642 }
4643 if (ids == NULL) {
4644 return error::kOutOfBounds;
4645 }
[email protected]269200b12010-11-18 22:53:064646 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104647 return error::kNoError;
4648}
4649
[email protected]269200b12010-11-18 22:53:064650void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104651 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574652 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104653 for (GLsizei ii = 0; ii < n; ++ii) {
4654 if (!id_allocator->MarkAsUsed(ids[ii])) {
4655 for (GLsizei jj = 0; jj < ii; ++jj) {
4656 id_allocator->FreeID(ids[jj]);
4657 }
[email protected]ab09b612013-03-11 22:11:514658 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:434659 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4660 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104661 return;
4662 }
4663 }
4664}
4665
[email protected]269200b12010-11-18 22:53:064666error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354667 uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104668 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4669 GLsizei n = static_cast<GLsizei>(c.n);
4670 uint32 data_size;
4671 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4672 return error::kOutOfBounds;
4673 }
4674 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4675 c.ids_shm_id, c.ids_shm_offset, data_size);
4676 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514677 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104678 return error::kNoError;
4679 }
4680 if (ids == NULL) {
4681 return error::kOutOfBounds;
4682 }
[email protected]269200b12010-11-18 22:53:064683 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104684 return error::kNoError;
4685}
4686
[email protected]a7266a92012-06-28 02:11:084687error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444688 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204689 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:464690 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:274691 glClear(mask);
4692 }
[email protected]a7266a92012-06-28 02:11:084693 return error::kNoError;
4694}
4695
[email protected]36cef8ce2010-03-16 07:34:454696void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4697 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:034698 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:064699 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4700 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514701 LOCAL_SET_GL_ERROR(
4702 GL_INVALID_OPERATION,
4703 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454704 return;
4705 }
[email protected]ae51d192010-04-27 00:48:034706 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:274707 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:034708 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:274709 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
4710 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514711 LOCAL_SET_GL_ERROR(
4712 GL_INVALID_OPERATION,
4713 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:034714 return;
4715 }
[email protected]ee2a79c32013-03-10 03:50:274716 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:034717 }
[email protected]ab09b612013-03-11 22:11:514718 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:034719 glFramebufferRenderbufferEXT(
4720 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:514721 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:264722 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:274723 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:284724 }
[email protected]9d3b2e12013-10-02 01:04:344725 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:444726 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464727 }
[email protected]81fc9d02013-03-14 23:53:324728 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:284729}
4730
[email protected]3a2e7c7b2010-08-06 01:12:284731void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464732 if (SetCapabilityState(cap, false)) {
4733 glDisable(cap);
4734 }
[email protected]3a2e7c7b2010-08-06 01:12:284735}
4736
4737void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464738 if (SetCapabilityState(cap, true)) {
4739 glEnable(cap);
4740 }
[email protected]3a2e7c7b2010-08-06 01:12:284741}
4742
[email protected]88a61bf2012-10-27 13:00:424743void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4744 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4745 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4746 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:284747}
4748
[email protected]b04e24c2013-01-08 18:35:254749void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:424750 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
4751 state_.sample_coverage_invert = (invert != 0);
4752 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:284753}
4754
[email protected]0d6bfdc2011-11-02 01:32:204755// Assumes framebuffer is complete.
4756void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:064757 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304758 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204759 // bind this to the DRAW point, clear then bind back to READ
4760 // TODO(gman): I don't think there is any guarantee that an FBO that
4761 // is complete on the READ attachment will be complete as a DRAW
4762 // attachment.
4763 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:064764 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:304765 }
[email protected]3a2e7c7b2010-08-06 01:12:284766 GLbitfield clear_bits = 0;
[email protected]4d8f0dd2013-03-09 14:37:064767 if (framebuffer->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
[email protected]297ca1c2011-06-20 23:08:464768 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:204769 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:464770 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:064771 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
4772 1.0f);
[email protected]3a2e7c7b2010-08-06 01:12:284773 glColorMask(true, true, true, true);
4774 clear_bits |= GL_COLOR_BUFFER_BIT;
4775 }
4776
[email protected]4d8f0dd2013-03-09 14:37:064777 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
4778 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284779 glClearStencil(0);
4780 glStencilMask(-1);
4781 clear_bits |= GL_STENCIL_BUFFER_BIT;
4782 }
4783
[email protected]4d8f0dd2013-03-09 14:37:064784 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
4785 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284786 glClearDepth(1.0f);
4787 glDepthMask(true);
4788 clear_bits |= GL_DEPTH_BUFFER_BIT;
4789 }
4790
4791 glDisable(GL_SCISSOR_TEST);
4792 glClear(clear_bits);
4793
[email protected]968351b2011-12-20 08:26:514794 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:064795 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:284796
[email protected]c007aa02010-09-02 22:22:404797 RestoreClearState();
4798
4799 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:064800 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
4801 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:484802 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:064803 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
4804 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:484805 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:404806 }
4807}
4808
4809void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:444810 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:244811 glClearColor(
4812 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
4813 state_.color_clear_alpha);
4814 glClearStencil(state_.stencil_clear);
4815 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:224816 if (state_.enable_flags.scissor_test) {
[email protected]3a2e7c7b2010-08-06 01:12:284817 glEnable(GL_SCISSOR_TEST);
4818 }
[email protected]36cef8ce2010-03-16 07:34:454819}
4820
4821GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:354822 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:304823 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:204824 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:454825 return GL_FRAMEBUFFER_COMPLETE;
4826 }
[email protected]0d6bfdc2011-11-02 01:32:204827 GLenum completeness = framebuffer->IsPossiblyComplete();
4828 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
4829 return completeness;
4830 }
[email protected]73276522012-11-09 05:50:204831 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:454832}
4833
4834void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:034835 GLenum target, GLenum attachment, GLenum textarget,
4836 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:164837 DoFramebufferTexture2DCommon(
4838 "glFramebufferTexture2D", target, attachment,
4839 textarget, client_texture_id, level, 0);
4840}
4841
4842void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
4843 GLenum target, GLenum attachment, GLenum textarget,
4844 GLuint client_texture_id, GLint level, GLsizei samples) {
4845 if (!features().multisampled_render_to_texture) {
4846 LOCAL_SET_GL_ERROR(
4847 GL_INVALID_OPERATION,
4848 "glFramebufferTexture2DMultisample", "function not available");
4849 return;
4850 }
4851 DoFramebufferTexture2DCommon(
4852 "glFramebufferTexture2DMultisample", target, attachment,
4853 textarget, client_texture_id, level, samples);
4854}
4855
4856void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
4857 const char* name, GLenum target, GLenum attachment, GLenum textarget,
4858 GLuint client_texture_id, GLint level, GLsizei samples) {
4859 if (samples > renderbuffer_manager()->max_samples()) {
4860 LOCAL_SET_GL_ERROR(
4861 GL_INVALID_VALUE,
4862 "glFramebufferTexture2DMultisample", "samples too large");
4863 return;
4864 }
[email protected]4d8f0dd2013-03-09 14:37:064865 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4866 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514867 LOCAL_SET_GL_ERROR(
4868 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:164869 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:454870 return;
4871 }
[email protected]ae51d192010-04-27 00:48:034872 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:494873 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:034874 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:494875 texture_ref = GetTexture(client_texture_id);
4876 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:514877 LOCAL_SET_GL_ERROR(
4878 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:164879 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:034880 return;
4881 }
[email protected]370eaf12013-05-18 09:19:494882 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:034883 }
[email protected]0d6bfdc2011-11-02 01:32:204884
[email protected]80eb6b52012-01-19 00:14:414885 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:514886 LOCAL_SET_GL_ERROR(
4887 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:164888 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:204889 return;
4890 }
4891
[email protected]91c94eb2013-10-22 10:32:544892 if (texture_ref)
4893 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
4894
[email protected]7d3c36e2013-07-12 14:13:164895 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
4896 if (0 == samples) {
4897 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
4898 } else {
4899 if (features().use_img_for_multisampled_render_to_texture) {
4900 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
4901 service_id, level, samples);
4902 } else {
4903 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
4904 service_id, level, samples);
4905 }
4906 }
4907 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:264908 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:164909 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
4910 samples);
[email protected]3a2e7c7b2010-08-06 01:12:284911 }
[email protected]9d3b2e12013-10-02 01:04:344912 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:444913 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464914 }
[email protected]91c94eb2013-10-22 10:32:544915
4916 if (texture_ref)
4917 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
4918
[email protected]81fc9d02013-03-14 23:53:324919 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:454920}
4921
4922void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
4923 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:064924 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4925 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514926 LOCAL_SET_GL_ERROR(
4927 GL_INVALID_OPERATION,
4928 "glFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454929 return;
4930 }
[email protected]74c1ec42010-08-12 01:55:574931 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:104932 const Framebuffer::Attachment* attachment_object =
4933 framebuffer->GetAttachment(attachment);
4934 *params = attachment_object ? attachment_object->object_name() : 0;
4935 } else {
[email protected]7d3c36e2013-07-12 14:13:164936 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
4937 features().use_img_for_multisampled_render_to_texture) {
4938 pname = GL_TEXTURE_SAMPLES_IMG;
4939 }
[email protected]62e65f02013-05-29 22:28:104940 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;
[email protected]7d3c36e2013-07-12 14:13:164964 case GL_RENDERBUFFER_SAMPLES_EXT:
4965 if (features().use_img_for_multisampled_render_to_texture) {
4966 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
4967 params);
4968 } else {
4969 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
4970 params);
4971 }
[email protected]ad84a3a2012-06-08 21:42:434972 default:
4973 glGetRenderbufferParameterivEXT(target, pname, params);
4974 break;
[email protected]b71f52c2010-06-18 22:20:204975 }
[email protected]36cef8ce2010-03-16 07:34:454976}
4977
[email protected]8e3e0662010-08-23 18:46:304978void GLES2DecoderImpl::DoBlitFramebufferEXT(
4979 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
4980 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
4981 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:444982 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]62e155e2012-10-23 22:43:154983 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:514984 LOCAL_SET_GL_ERROR(
4985 GL_INVALID_OPERATION,
4986 "glBlitFramebufferEXT", "function not available");
[email protected]680aa412013-10-31 18:08:014987 return;
[email protected]8e3e0662010-08-23 18:46:304988 }
[email protected]0c16343f2013-03-08 20:40:164989
4990 if (!CheckBoundFramebuffersValid("glBlitFramebufferEXT")) {
4991 return;
4992 }
4993
[email protected]d058bca2012-11-26 10:27:264994 glDisable(GL_SCISSOR_TEST);
[email protected]5094b0f2010-11-09 19:45:244995 if (IsAngle()) {
4996 glBlitFramebufferANGLE(
4997 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
4998 } else {
4999 glBlitFramebufferEXT(
5000 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5001 }
[email protected]d058bca2012-11-26 10:27:265002 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
[email protected]8e3e0662010-08-23 18:46:305003}
5004
5005void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
5006 GLenum target, GLsizei samples, GLenum internalformat,
5007 GLsizei width, GLsizei height) {
[email protected]7d3c36e2013-07-12 14:13:165008 if (!features().chromium_framebuffer_multisample &&
5009 !features().multisampled_render_to_texture) {
[email protected]ab09b612013-03-11 22:11:515010 LOCAL_SET_GL_ERROR(
5011 GL_INVALID_OPERATION,
5012 "glRenderbufferStorageMultisample", "function not available");
[email protected]8e3e0662010-08-23 18:46:305013 return;
5014 }
[email protected]8e3e0662010-08-23 18:46:305015
[email protected]ed9f9cd2013-02-27 21:12:355016 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205017 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5018 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515019 LOCAL_SET_GL_ERROR(
5020 GL_INVALID_OPERATION,
5021 "glRenderbufferStorageMultisample", "no renderbuffer bound");
[email protected]0d6bfdc2011-11-02 01:32:205022 return;
5023 }
5024
[email protected]84afefa2011-10-19 21:45:535025 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515026 LOCAL_SET_GL_ERROR(
5027 GL_INVALID_VALUE,
5028 "glRenderbufferStorageMultisample", "samples too large");
[email protected]84afefa2011-10-19 21:45:535029 return;
5030 }
5031
5032 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5033 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515034 LOCAL_SET_GL_ERROR(
5035 GL_INVALID_VALUE,
5036 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535037 return;
5038 }
5039
[email protected]7989c9e2013-01-23 06:39:265040 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235041 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5042 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515043 LOCAL_SET_GL_ERROR(
5044 GL_OUT_OF_MEMORY,
5045 "glRenderbufferStorageMultsample", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265046 return;
[email protected]8e3e0662010-08-23 18:46:305047 }
5048
[email protected]7989c9e2013-01-23 06:39:265049 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515050 LOCAL_SET_GL_ERROR(
5051 GL_OUT_OF_MEMORY,
5052 "glRenderbufferStorageMultsample", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265053 return;
5054 }
5055
[email protected]8e102e102013-09-20 22:50:235056 GLenum impl_format =
5057 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5058 internalformat);
[email protected]ab09b612013-03-11 22:11:515059 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisample");
[email protected]866b91c52011-03-23 14:38:085060 if (IsAngle()) {
5061 glRenderbufferStorageMultisampleANGLE(
5062 target, samples, impl_format, width, height);
[email protected]7d3c36e2013-07-12 14:13:165063 } else if (features().use_img_for_multisampled_render_to_texture) {
5064 glRenderbufferStorageMultisampleIMG(
5065 target, samples, impl_format, width, height);
[email protected]866b91c52011-03-23 14:38:085066 } else {
5067 glRenderbufferStorageMultisampleEXT(
5068 target, samples, impl_format, width, height);
5069 }
[email protected]ab09b612013-03-11 22:11:515070 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisample");
[email protected]9edc6b22010-12-23 02:00:265071 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105072
5073 if (workarounds().validate_multisample_buffer_allocation) {
5074 if (!VerifyMultisampleRenderbufferIntegrity(
5075 renderbuffer->service_id(), impl_format)) {
5076 LOCAL_SET_GL_ERROR(
5077 GL_OUT_OF_MEMORY,
5078 "glRenderbufferStorageMultisample", "out of memory");
5079 return;
5080 }
5081 }
5082
[email protected]968351b2011-12-20 08:26:515083 // TODO(gman): If renderbuffers tracked which framebuffers they were
5084 // attached to we could just mark those framebuffers as not complete.
5085 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205086 renderbuffer_manager()->SetInfo(
5087 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265088 }
[email protected]8e3e0662010-08-23 18:46:305089}
5090
[email protected]4a4c18b2013-09-13 22:50:105091// This function validates the allocation of a multisampled renderbuffer
5092// by clearing it to a key color, blitting the contents to a texture, and
5093// reading back the color to ensure it matches the key.
5094bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5095 GLuint renderbuffer, GLenum format) {
5096
5097 // Only validate color buffers.
5098 // These formats have been selected because they are very common or are known
5099 // to be used by the WebGL backbuffer. If problems are observed with other
5100 // color formats they can be added here.
5101 switch(format) {
5102 case GL_RGB:
5103 case GL_RGB8:
5104 case GL_RGBA:
5105 case GL_RGBA8:
5106 break;
5107 default:
5108 return true;
5109 }
5110
5111 GLint draw_framebuffer, read_framebuffer;
5112
5113 // Cache framebuffer and texture bindings.
5114 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5115 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5116
5117 if (!validation_texture_) {
5118 GLint bound_texture;
5119 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5120
5121 // Create additional resources needed for the verification.
5122 glGenTextures(1, &validation_texture_);
5123 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5124 glGenFramebuffersEXT(1, &validation_fbo_);
5125
5126 // Texture only needs to be 1x1.
5127 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5128 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5129 GL_UNSIGNED_BYTE, NULL);
5130
5131 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5132 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5133 GL_TEXTURE_2D, validation_texture_, 0);
5134
5135 glBindTexture(GL_TEXTURE_2D, bound_texture);
5136 }
5137
5138 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5139 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5140 GL_RENDERBUFFER, renderbuffer);
5141
5142 // Cache current state and reset it to the values we require.
5143 GLboolean scissor_enabled = false;
5144 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5145 if (scissor_enabled)
5146 glDisable(GL_SCISSOR_TEST);
5147
5148 GLboolean color_mask[4] = {true, true, true, true};
5149 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
5150 glColorMask(true, true, true, true);
5151
5152 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5153 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5154 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5155
5156 // Clear the buffer to the desired key color.
5157 glClear(GL_COLOR_BUFFER_BIT);
5158
5159 // Blit from the multisample buffer to a standard texture.
5160 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5161 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5162
5163 glBlitFramebufferEXT(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
5164
5165 // Read a pixel from the buffer.
5166 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5167
5168 unsigned char pixel[3] = {0, 0, 0};
5169 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5170
5171 // Detach the renderbuffer.
5172 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5173 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5174 GL_RENDERBUFFER, 0);
5175
5176 // Restore cached state.
5177 if (scissor_enabled)
5178 glEnable(GL_SCISSOR_TEST);
5179
5180 glColorMask(color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
5181 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5182 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5183 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5184
5185 // Return true if the pixel matched the desired key color.
5186 return (pixel[0] == 0xFF &&
5187 pixel[1] == 0x00 &&
5188 pixel[2] == 0xFF);
5189}
5190
[email protected]36cef8ce2010-03-16 07:34:455191void GLES2DecoderImpl::DoRenderbufferStorage(
5192 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355193 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205194 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5195 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515196 LOCAL_SET_GL_ERROR(
5197 GL_INVALID_OPERATION,
5198 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455199 return;
5200 }
[email protected]876f6fee2010-08-02 23:10:325201
[email protected]84afefa2011-10-19 21:45:535202 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5203 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515204 LOCAL_SET_GL_ERROR(
5205 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535206 return;
5207 }
5208
[email protected]7989c9e2013-01-23 06:39:265209 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235210 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5211 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515212 LOCAL_SET_GL_ERROR(
5213 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265214 return;
5215 }
5216
5217 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515218 LOCAL_SET_GL_ERROR(
5219 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265220 return;
[email protected]b71f52c2010-06-18 22:20:205221 }
[email protected]876f6fee2010-08-02 23:10:325222
[email protected]ab09b612013-03-11 22:11:515223 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265224 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:235225 target,
5226 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5227 internalformat),
5228 width,
5229 height);
[email protected]ab09b612013-03-11 22:11:515230 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265231 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515232 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5233 // we could just mark those framebuffers as not complete.
5234 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205235 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265236 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265237 }
[email protected]36cef8ce2010-03-16 07:34:455238}
5239
[email protected]df37b9932013-03-08 05:21:425240void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385241 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425242 Program* program = GetProgramInfoNotShader(
5243 program_id, "glLinkProgram");
5244 if (!program) {
[email protected]a93bb842010-02-16 23:03:475245 return;
5246 }
[email protected]05afda12011-01-20 00:17:345247
[email protected]df37b9932013-03-08 05:21:425248 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395249 ShaderTranslator* vertex_translator = NULL;
5250 ShaderTranslator* fragment_translator = NULL;
5251 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115252 vertex_translator = vertex_translator_.get();
5253 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395254 }
[email protected]df37b9932013-03-08 05:21:425255 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115256 vertex_translator,
5257 fragment_translator,
5258 feature_info_.get(),
5259 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425260 if (program == state_.current_program.get()) {
[email protected]62e155e2012-10-23 22:43:155261 if (workarounds().use_current_program_after_successful_link) {
[email protected]df37b9932013-03-08 05:21:425262 glUseProgram(program->service_id());
[email protected]c2a3caf12012-10-23 19:32:005263 }
[email protected]df37b9932013-03-08 05:21:425264 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545265 }
5266 }
[email protected]07f54fcc2009-12-22 02:46:305267};
5268
[email protected]3916c97e2010-02-25 03:20:505269void GLES2DecoderImpl::DoTexParameterf(
5270 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445271 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5272 &state_, target);
[email protected]02965c22013-03-09 02:40:075273 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515274 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245275 return;
[email protected]07f54fcc2009-12-22 02:46:305276 }
[email protected]cbb22e42011-05-12 23:36:245277
[email protected]02965c22013-03-09 02:40:075278 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505279 "glTexParameterf", GetErrorState(), texture, pname,
5280 static_cast<GLint>(param));
[email protected]07f54fcc2009-12-22 02:46:305281}
5282
[email protected]3916c97e2010-02-25 03:20:505283void GLES2DecoderImpl::DoTexParameteri(
5284 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445285 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5286 &state_, target);
[email protected]02965c22013-03-09 02:40:075287 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515288 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245289 return;
[email protected]3916c97e2010-02-25 03:20:505290 }
[email protected]cbb22e42011-05-12 23:36:245291
[email protected]02965c22013-03-09 02:40:075292 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505293 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505294}
5295
5296void GLES2DecoderImpl::DoTexParameterfv(
5297 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445298 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5299 &state_, target);
[email protected]02965c22013-03-09 02:40:075300 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515301 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245302 return;
[email protected]3916c97e2010-02-25 03:20:505303 }
[email protected]cbb22e42011-05-12 23:36:245304
[email protected]02965c22013-03-09 02:40:075305 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505306 "glTexParameterfv", GetErrorState(), texture, pname,
5307 static_cast<GLint>(params[0]));
[email protected]3916c97e2010-02-25 03:20:505308}
5309
5310void GLES2DecoderImpl::DoTexParameteriv(
5311 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445312 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5313 &state_, target);
[email protected]02965c22013-03-09 02:40:075314 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515315 LOCAL_SET_GL_ERROR(
5316 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245317 return;
[email protected]3916c97e2010-02-25 03:20:505318 }
[email protected]cbb22e42011-05-12 23:36:245319
[email protected]02965c22013-03-09 02:40:075320 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505321 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505322}
5323
[email protected]939e7362010-05-13 20:49:105324bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115325 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435326 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515327 LOCAL_SET_GL_ERROR(
5328 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435329 return false;
[email protected]939e7362010-05-13 20:49:105330 }
[email protected]e259eb412012-10-13 05:47:245331 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515332 LOCAL_SET_GL_ERROR(
5333 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105334 return false;
5335 }
5336 return true;
5337}
5338
5339bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5340 GLint location, const char* function_name) {
5341 if (!CheckCurrentProgram(function_name)) {
5342 return false;
5343 }
5344 return location != -1;
5345}
5346
[email protected]476ccb72012-12-06 15:52:525347namespace {
5348
5349static const GLenum valid_int_vec1_types_list[] = {
5350 GL_INT,
5351 GL_BOOL,
5352 GL_SAMPLER_2D,
5353 GL_SAMPLER_2D_RECT_ARB,
5354 GL_SAMPLER_CUBE,
5355 GL_SAMPLER_EXTERNAL_OES,
5356};
5357
5358static const GLenum valid_int_vec2_types_list[] = {
5359 GL_INT_VEC2,
5360 GL_BOOL_VEC2,
5361};
5362
5363static const GLenum valid_int_vec3_types_list[] = {
5364 GL_INT_VEC3,
5365 GL_BOOL_VEC3,
5366};
5367
5368static const GLenum valid_int_vec4_types_list[] = {
5369 GL_INT_VEC4,
5370 GL_BOOL_VEC4,
5371};
5372
5373static const GLenum valid_float_vec1_types_list[] = {
5374 GL_FLOAT,
5375 GL_BOOL,
5376};
5377
5378static const GLenum valid_float_vec2_types_list[] = {
5379 GL_FLOAT_VEC2,
5380 GL_BOOL_VEC2,
5381};
5382
5383static const GLenum valid_float_vec3_types_list[] = {
5384 GL_FLOAT_VEC3,
5385 GL_BOOL_VEC3,
5386};
5387
5388static const GLenum valid_float_vec4_types_list[] = {
5389 GL_FLOAT_VEC4,
5390 GL_BOOL_VEC4,
5391};
5392
5393static const GLenum valid_float_mat2_types_list[] = {
5394 GL_FLOAT_MAT2,
5395};
5396
5397static const GLenum valid_float_mat3_types_list[] = {
5398 GL_FLOAT_MAT3,
5399};
5400
5401static const GLenum valid_float_mat4_types_list[] = {
5402 GL_FLOAT_MAT4,
5403};
5404
5405static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec1_base_info = {
5406 valid_int_vec1_types_list,
5407 arraysize(valid_int_vec1_types_list),
5408};
5409
5410static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec2_base_info = {
5411 valid_int_vec2_types_list,
5412 arraysize(valid_int_vec2_types_list),
5413};
5414
5415static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec3_base_info = {
5416 valid_int_vec3_types_list,
5417 arraysize(valid_int_vec3_types_list),
5418};
5419
5420static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec4_base_info = {
5421 valid_int_vec4_types_list,
5422 arraysize(valid_int_vec4_types_list),
5423};
5424
5425static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec1_base_info = {
5426 valid_float_vec1_types_list,
5427 arraysize(valid_float_vec1_types_list),
5428};
5429
5430static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec2_base_info = {
5431 valid_float_vec2_types_list,
5432 arraysize(valid_float_vec2_types_list),
5433};
5434
5435static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec3_base_info = {
5436 valid_float_vec3_types_list,
5437 arraysize(valid_float_vec3_types_list),
5438};
5439
5440static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec4_base_info = {
5441 valid_float_vec4_types_list,
5442 arraysize(valid_float_vec4_types_list),
5443};
5444
5445static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat2_base_info = {
5446 valid_float_mat2_types_list,
5447 arraysize(valid_float_mat2_types_list),
5448};
5449
5450static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat3_base_info = {
5451 valid_float_mat3_types_list,
5452 arraysize(valid_float_mat3_types_list),
5453};
5454
5455static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat4_base_info = {
5456 valid_float_mat4_types_list,
5457 arraysize(valid_float_mat4_types_list),
5458};
5459
5460} // anonymous namespace.
5461
[email protected]43c2f1f2011-03-25 18:35:365462bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:125463 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:525464 const GLES2DecoderImpl::BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:125465 GLint* real_location, GLenum* type, GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365466 DCHECK(type);
5467 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125468 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525469
[email protected]1b0a6752012-02-22 03:44:125470 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105471 return false;
5472 }
[email protected]43c2f1f2011-03-25 18:35:365473 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355474 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245475 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125476 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365477 if (!info) {
[email protected]ab09b612013-03-11 22:11:515478 LOCAL_SET_GL_ERROR(
5479 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105480 return false;
5481 }
[email protected]476ccb72012-12-06 15:52:525482 bool okay = false;
5483 for (size_t ii = 0; ii < base_info.num_valid_types; ++ii) {
5484 if (base_info.valid_types[ii] == info->type) {
5485 okay = true;
5486 break;
5487 }
5488 }
5489 if (!okay) {
[email protected]ab09b612013-03-11 22:11:515490 LOCAL_SET_GL_ERROR(
5491 GL_INVALID_OPERATION, function_name,
5492 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525493 return false;
5494 }
[email protected]43c2f1f2011-03-25 18:35:365495 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515496 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435497 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365498 return false;
5499 }
5500 *count = std::min(info->size - array_index, *count);
5501 if (*count <= 0) {
5502 return false;
5503 }
5504 *type = info->type;
[email protected]939e7362010-05-13 20:49:105505 return true;
5506}
5507
[email protected]1b0a6752012-02-22 03:44:125508void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5509 GLenum type = 0;
5510 GLsizei count = 1;
5511 GLint real_location = -1;
5512 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525513 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5514 &real_location, &type, &count)) {
[email protected]3916c97e2010-02-25 03:20:505515 return;
5516 }
[email protected]e259eb412012-10-13 05:47:245517 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025518 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515519 LOCAL_SET_GL_ERROR(
5520 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465521 return;
5522 }
[email protected]1b0a6752012-02-22 03:44:125523 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505524}
5525
5526void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125527 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365528 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125529 GLint real_location = -1;
5530 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525531 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5532 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365533 return;
5534 }
[email protected]74727112012-06-13 21:18:085535 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5536 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245537 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025538 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515539 LOCAL_SET_GL_ERROR(
5540 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465541 return;
5542 }
[email protected]43c2f1f2011-03-25 18:35:365543 }
[email protected]1b0a6752012-02-22 03:44:125544 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505545}
5546
[email protected]939e7362010-05-13 20:49:105547void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125548 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365549 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125550 GLint real_location = -1;
5551 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525552 fake_location, "glUniform1fv", valid_float_vec1_base_info,
5553 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105554 return;
5555 }
5556 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:555557 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:105558 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535559 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105560 }
[email protected]1b0a6752012-02-22 03:44:125561 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105562 } else {
[email protected]1b0a6752012-02-22 03:44:125563 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105564 }
5565}
5566
5567void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125568 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365569 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125570 GLint real_location = -1;
5571 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525572 fake_location, "glUniform2fv", valid_float_vec2_base_info,
5573 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105574 return;
5575 }
5576 if (type == GL_BOOL_VEC2) {
5577 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:555578 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105579 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535580 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105581 }
[email protected]1b0a6752012-02-22 03:44:125582 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105583 } else {
[email protected]1b0a6752012-02-22 03:44:125584 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105585 }
5586}
5587
5588void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125589 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365590 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125591 GLint real_location = -1;
5592 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525593 fake_location, "glUniform3fv", valid_float_vec3_base_info,
5594 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105595 return;
5596 }
5597 if (type == GL_BOOL_VEC3) {
5598 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:555599 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105600 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535601 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105602 }
[email protected]1b0a6752012-02-22 03:44:125603 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105604 } else {
[email protected]1b0a6752012-02-22 03:44:125605 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105606 }
5607}
5608
5609void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125610 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365611 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125612 GLint real_location = -1;
5613 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525614 fake_location, "glUniform4fv", valid_float_vec4_base_info,
5615 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105616 return;
5617 }
5618 if (type == GL_BOOL_VEC4) {
5619 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:555620 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105621 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535622 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105623 }
[email protected]1b0a6752012-02-22 03:44:125624 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105625 } else {
[email protected]1b0a6752012-02-22 03:44:125626 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105627 }
5628}
5629
[email protected]43c2f1f2011-03-25 18:35:365630void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125631 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365632 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125633 GLint real_location = -1;
5634 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525635 fake_location, "glUniform2iv", valid_int_vec2_base_info,
5636 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365637 return;
5638 }
[email protected]1b0a6752012-02-22 03:44:125639 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365640}
5641
5642void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125643 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365644 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125645 GLint real_location = -1;
5646 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525647 fake_location, "glUniform3iv", valid_int_vec3_base_info,
5648 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365649 return;
5650 }
[email protected]1b0a6752012-02-22 03:44:125651 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365652}
5653
5654void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125655 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365656 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125657 GLint real_location = -1;
5658 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525659 fake_location, "glUniform4iv", valid_int_vec4_base_info,
5660 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365661 return;
5662 }
[email protected]1b0a6752012-02-22 03:44:125663 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365664}
5665
5666void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:125667 GLint fake_location, GLsizei count, GLboolean transpose,
5668 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365669 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125670 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365671 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525672 fake_location, "glUniformMatrix2fv", valid_float_mat2_base_info,
5673 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365674 return;
5675 }
[email protected]1b0a6752012-02-22 03:44:125676 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365677}
5678
5679void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:125680 GLint fake_location, GLsizei count, GLboolean transpose,
5681 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365682 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125683 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365684 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525685 fake_location, "glUniformMatrix3fv", valid_float_mat3_base_info,
5686 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365687 return;
5688 }
[email protected]1b0a6752012-02-22 03:44:125689 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365690}
5691
5692void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:125693 GLint fake_location, GLsizei count, GLboolean transpose,
5694 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365695 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125696 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365697 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525698 fake_location, "glUniformMatrix4fv", valid_float_mat4_base_info,
5699 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365700 return;
5701 }
[email protected]1b0a6752012-02-22 03:44:125702 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365703}
5704
[email protected]df37b9932013-03-08 05:21:425705void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:035706 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:425707 Program* program = NULL;
5708 if (program_id) {
5709 program = GetProgramInfoNotShader(program_id, "glUseProgram");
5710 if (!program) {
[email protected]ae51d192010-04-27 00:48:035711 return;
5712 }
[email protected]df37b9932013-03-08 05:21:425713 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:505714 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:515715 LOCAL_SET_GL_ERROR(
5716 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:505717 return;
5718 }
[email protected]df37b9932013-03-08 05:21:425719 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:505720 }
[email protected]7cd76fd2013-06-02 21:11:115721 if (state_.current_program.get()) {
5722 program_manager()->UnuseProgram(shader_manager(),
5723 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:145724 }
[email protected]df37b9932013-03-08 05:21:425725 state_.current_program = program;
5726 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:545727 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:115728 if (state_.current_program.get()) {
5729 program_manager()->UseProgram(state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:145730 }
[email protected]3916c97e2010-02-25 03:20:505731}
5732
[email protected]ab09b612013-03-11 22:11:515733void GLES2DecoderImpl::RenderWarning(
5734 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:325735 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015736}
5737
[email protected]ab09b612013-03-11 22:11:515738void GLES2DecoderImpl::PerformanceWarning(
5739 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:505740 logger_.LogMessage(filename, line,
5741 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015742}
5743
[email protected]e8dc5662013-10-17 23:28:295744void GLES2DecoderImpl::UpdateStreamTextureIfNeeded(Texture* texture,
5745 GLuint texture_unit_index) {
[email protected]e56131d22013-07-28 16:14:115746 if (texture && texture->IsStreamTexture()) {
5747 DCHECK(stream_texture_manager());
5748 StreamTexture* stream_tex =
5749 stream_texture_manager()->LookupStreamTexture(texture->service_id());
[email protected]e8dc5662013-10-17 23:28:295750 if (stream_tex) {
5751 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]e56131d22013-07-28 16:14:115752 stream_tex->Update();
[email protected]e8dc5662013-10-17 23:28:295753 }
[email protected]e56131d22013-07-28 16:14:115754 }
5755}
5756
[email protected]91c94eb2013-10-22 10:32:545757void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
5758 Texture* texture, GLenum textarget) {
5759 // This might be supported in the future.
5760 if (textarget != GL_TEXTURE_2D)
5761 return;
5762 // Image is already in use if texture is attached to a framebuffer.
5763 if (texture && !texture->IsAttachedToFramebuffer()) {
5764 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
5765 if (image) {
5766 ScopedGLErrorSuppressor suppressor(
5767 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
5768 GetErrorState());
5769 glBindTexture(textarget, texture->service_id());
5770 image->WillUseTexImage();
[email protected]ce296892013-10-24 22:04:365771 RestoreCurrentTexture2DBindings(&state_);
[email protected]91c94eb2013-10-22 10:32:545772 }
5773 }
5774}
5775
5776void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
5777 Texture* texture, GLenum textarget) {
5778 // This might be supported in the future.
5779 if (textarget != GL_TEXTURE_2D)
5780 return;
5781 // Image is still in use if texture is attached to a framebuffer.
5782 if (texture && !texture->IsAttachedToFramebuffer()) {
5783 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
5784 if (image) {
5785 ScopedGLErrorSuppressor suppressor(
5786 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
5787 GetErrorState());
5788 glBindTexture(textarget, texture->service_id());
5789 image->DidUseTexImage();
[email protected]ce296892013-10-24 22:04:365790 RestoreCurrentTexture2DBindings(&state_);
[email protected]91c94eb2013-10-22 10:32:545791 }
5792 }
5793}
5794
[email protected]e56131d22013-07-28 16:14:115795bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:115796 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:545797 if (!texture_manager()->HaveUnrenderableTextures() &&
5798 !texture_manager()->HaveImages() &&
5799 !features().oes_egl_image_external) {
[email protected]e56131d22013-07-28 16:14:115800 return true;
[email protected]ef526492010-06-02 23:12:255801 }
[email protected]e2367b42013-05-31 03:37:215802
[email protected]ef526492010-06-02 23:12:255803 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:355804 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:245805 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505806 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355807 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245808 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505809 DCHECK(uniform_info);
5810 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5811 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025812 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245813 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:545814 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:365815 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:545816 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
5817 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:255818 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:505819 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5820 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:545821 textarget,
[email protected]00f893d2010-08-24 18:55:495822 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:515823 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:015824 std::string("texture bound to texture unit ") +
5825 base::IntToString(texture_unit_index) +
[email protected]ad9b7f8b2013-06-17 07:36:295826 " is not renderable. It maybe non-power-of-2 and have"
5827 " incompatible texture filtering or is not"
5828 " 'texture complete'");
[email protected]91c94eb2013-10-22 10:32:545829 continue;
[email protected]3916c97e2010-02-25 03:20:505830 }
[email protected]91c94eb2013-10-22 10:32:545831
5832 Texture* texture = texture_ref->texture();
5833 if (textarget == GL_TEXTURE_2D) {
5834 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
5835 if (image && !texture->IsAttachedToFramebuffer()) {
5836 ScopedGLErrorSuppressor suppressor(
5837 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
5838 textures_set = true;
5839 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5840 image->WillUseTexImage();
5841 continue;
5842 }
5843 }
5844
5845 UpdateStreamTextureIfNeeded(texture, texture_unit_index);
[email protected]3916c97e2010-02-25 03:20:505846 }
5847 // else: should this be an error?
5848 }
5849 }
[email protected]e56131d22013-07-28 16:14:115850 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:505851}
5852
[email protected]91c94eb2013-10-22 10:32:545853void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:115854 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:355855 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:115856 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:505857 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355858 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245859 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:505860 DCHECK(uniform_info);
5861 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5862 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025863 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245864 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:115865 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:545866 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:495867 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:505868 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:495869 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:115870 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
5871 ? texture_unit.bound_texture_2d.get()
5872 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:505873 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:495874 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:545875 continue;
5876 }
5877
5878 Texture* texture = texture_ref->texture();
5879 if (texture_unit.bind_target == GL_TEXTURE_2D) {
5880 gfx::GLImage* image = texture->GetLevelImage(
5881 texture_unit.bind_target, 0);
5882 if (image && !texture->IsAttachedToFramebuffer()) {
5883 ScopedGLErrorSuppressor suppressor(
5884 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
5885 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
5886 image->DidUseTexImage();
5887 continue;
5888 }
[email protected]3916c97e2010-02-25 03:20:505889 }
5890 }
5891 }
5892 }
5893 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:245894 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:305895}
5896
[email protected]0d6bfdc2011-11-02 01:32:205897bool GLES2DecoderImpl::ClearUnclearedTextures() {
5898 // Only check if there are some uncleared textures.
5899 if (!texture_manager()->HaveUnsafeTextures()) {
5900 return true;
5901 }
5902
5903 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:115904 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:355905 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:115906 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:205907 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:355908 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:245909 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:205910 DCHECK(uniform_info);
5911 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
5912 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:025913 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:245914 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:495915 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:365916 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:495917 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
5918 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:205919 return false;
5920 }
5921 }
5922 }
5923 }
5924 }
5925 }
5926 return true;
5927}
5928
[email protected]c6aef902012-02-14 03:31:425929bool GLES2DecoderImpl::IsDrawValid(
[email protected]ad84a3a2012-06-08 21:42:435930 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
[email protected]689fa1c52010-06-09 18:35:035931 // NOTE: We specifically do not check current_program->IsValid() because
5932 // it could never be invalid since glUseProgram would have failed. While
5933 // glLinkProgram could later mark the program as invalid the previous
5934 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:115935 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:505936 // The program does not exist.
5937 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:515938 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:505939 return false;
5940 }
[email protected]c6aef902012-02-14 03:31:425941
[email protected]7cd76fd2013-06-02 21:11:115942 return state_.vertex_attrib_manager
5943 ->ValidateBindings(function_name,
5944 this,
5945 feature_info_.get(),
5946 state_.current_program.get(),
5947 max_vertex_accessed,
5948 primcount);
[email protected]b1122982010-05-17 23:04:245949}
5950
[email protected]c13e1da62011-09-09 21:48:305951bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:435952 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:305953 DCHECK(simulated);
5954 *simulated = false;
5955
[email protected]876f6fee2010-08-02 23:10:325956 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:305957 return true;
[email protected]876f6fee2010-08-02 23:10:325958
[email protected]ac77603c72013-03-08 13:52:065959 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:355960 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:245961 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:245962 bool attrib_0_used =
5963 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:065964 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:305965 return true;
[email protected]b1122982010-05-17 23:04:245966 }
5967
[email protected]b1122982010-05-17 23:04:245968 // Make a buffer with a single repeated vec4 value enough to
5969 // simulate the constant value that is supposed to be here.
5970 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:305971 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:475972 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:305973
5974 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:475975 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:305976 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:515977 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305978 return false;
5979 }
5980
[email protected]ab09b612013-03-11 22:11:515981 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:015982 "Attribute 0 is disabled. This has signficant performance penalty");
5983
[email protected]ab09b612013-03-11 22:11:515984 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:305985 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
5986
[email protected]8f0b86c2f2012-04-10 05:48:285987 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
5988 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:495989 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:305990 GLenum error = glGetError();
5991 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:515992 LOCAL_SET_GL_ERROR(
5993 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:305994 return false;
5995 }
[email protected]fc753442011-02-04 19:49:495996 }
[email protected]af6380962012-11-29 23:24:135997
5998 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:285999 if (new_buffer ||
6000 (attrib_0_used &&
6001 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136002 (value.v[0] != attrib_0_value_.v[0] ||
6003 value.v[1] != attrib_0_value_.v[1] ||
6004 value.v[2] != attrib_0_value_.v[2] ||
6005 value.v[3] != attrib_0_value_.v[3])))) {
6006 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496007 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6008 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136009 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246010 attrib_0_size_ = size_needed;
6011 }
6012
6013 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6014
[email protected]ac77603c72013-03-08 13:52:066015 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426016 glVertexAttribDivisorANGLE(0, 0);
6017
[email protected]c13e1da62011-09-09 21:48:306018 *simulated = true;
[email protected]b1122982010-05-17 23:04:246019 return true;
[email protected]b1122982010-05-17 23:04:246020}
6021
[email protected]ac77603c72013-03-08 13:52:066022void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib_index) {
6023 const VertexAttrib* attrib =
6024 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
6025 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6026 Buffer* buffer = attrib->buffer();
[email protected]b10492f2013-03-08 05:24:076027 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
[email protected]b1122982010-05-17 23:04:246028 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066029 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6030 attrib->gl_stride(), ptr);
6031 if (attrib->divisor())
6032 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246033 glBindBuffer(
6034 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116035 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6036 : 0);
[email protected]43410e92012-04-20 17:06:286037
[email protected]265f8992012-07-20 01:03:146038 // Never touch vertex attribute 0's state (in particular, never
6039 // disable it) when running on desktop GL because it will never be
6040 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066041 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146042 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066043 if (attrib->enabled()) {
6044 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146045 } else {
[email protected]ac77603c72013-03-08 13:52:066046 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146047 }
[email protected]43410e92012-04-20 17:06:286048 }
[email protected]b1122982010-05-17 23:04:246049}
[email protected]07f54fcc2009-12-22 02:46:306050
[email protected]8fbedc02010-11-18 18:43:406051bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436052 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426053 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406054 DCHECK(simulated);
6055 *simulated = false;
6056 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6057 return true;
6058
[email protected]e259eb412012-10-13 05:47:246059 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406060 return true;
6061 }
6062
[email protected]ab09b612013-03-11 22:11:516063 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016064 "GL_FIXED attributes have a signficant performance penalty");
6065
[email protected]8fbedc02010-11-18 18:43:406066 // NOTE: we could be smart and try to check if a buffer is used
6067 // twice in 2 different attribs, find the overlapping parts and therefore
6068 // duplicate the minimum amount of data but this whole code path is not meant
6069 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6070 // tests so we just add to the buffer attrib used.
6071
[email protected]c13e1da62011-09-09 21:48:306072 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066073 const VertexAttribManager::VertexAttribList& enabled_attribs =
6074 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6075 for (VertexAttribManager::VertexAttribList::const_iterator it =
6076 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6077 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356078 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066079 state_.current_program->GetAttribInfoByLocation(attrib->index());
6080 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6081 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426082 GLuint num_vertices = max_accessed + 1;
6083 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516084 LOCAL_SET_GL_ERROR(
6085 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426086 return false;
6087 }
[email protected]8fbedc02010-11-18 18:43:406088 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066089 attrib->CanAccess(max_accessed) &&
6090 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476091 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066092 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476093 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516094 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436095 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406096 return false;
6097 }
6098 }
6099 }
6100
[email protected]3aad1a32012-09-07 20:54:476101 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6102 uint32 size_needed = 0;
6103 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306104 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516105 LOCAL_SET_GL_ERROR(
6106 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406107 return false;
6108 }
6109
[email protected]ab09b612013-03-11 22:11:516110 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406111
6112 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306113 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406114 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306115 GLenum error = glGetError();
6116 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516117 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436118 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306119 return false;
6120 }
[email protected]8fbedc02010-11-18 18:43:406121 }
6122
6123 // Copy the elements and convert to float
6124 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066125 for (VertexAttribManager::VertexAttribList::const_iterator it =
6126 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6127 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356128 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066129 state_.current_program->GetAttribInfoByLocation(attrib->index());
6130 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426131 max_vertex_accessed);
6132 GLuint num_vertices = max_accessed + 1;
6133 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516134 LOCAL_SET_GL_ERROR(
6135 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426136 return false;
6137 }
[email protected]8fbedc02010-11-18 18:43:406138 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066139 attrib->CanAccess(max_accessed) &&
6140 attrib->type() == GL_FIXED) {
6141 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:406142 int size = num_elements * num_vertices;
[email protected]40d90a22013-04-09 03:39:556143 scoped_ptr<float[]> data(new float[size]);
[email protected]8fbedc02010-11-18 18:43:406144 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:066145 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:406146 const int32* end = src + num_elements;
6147 float* dst = data.get();
6148 while (src != end) {
6149 *dst++ = static_cast<float>(*src++) / 65536.0f;
6150 }
6151 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
6152 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066153 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406154 reinterpret_cast<GLvoid*>(offset));
6155 offset += size;
6156 }
6157 }
6158 *simulated = true;
6159 return true;
6160}
6161
6162void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6163 // There's no need to call glVertexAttribPointer because we shadow all the
6164 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246165 glBindBuffer(
6166 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116167 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6168 : 0);
[email protected]8fbedc02010-11-18 18:43:406169}
6170
[email protected]ad84a3a2012-06-08 21:42:436171error::Error GLES2DecoderImpl::DoDrawArrays(
6172 const char* function_name,
6173 bool instanced,
6174 GLenum mode,
6175 GLint first,
6176 GLsizei count,
6177 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:086178 if (ShouldDeferDraws())
6179 return error::kDeferCommandUntilLater;
[email protected]38d139d2011-07-14 00:38:436180 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516181 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436182 return error::kNoError;
6183 }
6184 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516185 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436186 return error::kNoError;
6187 }
[email protected]c6aef902012-02-14 03:31:426188 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516189 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426190 return error::kNoError;
6191 }
[email protected]ad84a3a2012-06-08 21:42:436192 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436193 return error::kNoError;
6194 }
6195 // We have to check this here because the prototype for glDrawArrays
6196 // is GLint not GLsizei.
6197 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516198 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436199 return error::kNoError;
6200 }
6201
[email protected]c6aef902012-02-14 03:31:426202 if (count == 0 || (instanced && primcount == 0)) {
[email protected]ab09b612013-03-11 22:11:516203 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436204 return error::kNoError;
6205 }
6206
6207 GLuint max_vertex_accessed = first + count - 1;
[email protected]ad84a3a2012-06-08 21:42:436208 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206209 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516210 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206211 return error::kNoError;
6212 }
[email protected]c13e1da62011-09-09 21:48:306213 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436214 if (!SimulateAttrib0(
6215 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306216 return error::kNoError;
6217 }
[email protected]38d139d2011-07-14 00:38:436218 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436219 if (SimulateFixedAttribs(
6220 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6221 primcount)) {
[email protected]e56131d22013-07-28 16:14:116222 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436223 ApplyDirtyState();
[email protected]c6aef902012-02-14 03:31:426224 if (!instanced) {
6225 glDrawArrays(mode, first, count);
6226 } else {
6227 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6228 }
[email protected]22e3f552012-03-13 01:54:196229 ProcessPendingQueries();
[email protected]38d139d2011-07-14 00:38:436230 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546231 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436232 }
6233 if (simulated_fixed_attribs) {
6234 RestoreStateForSimulatedFixedAttribs();
6235 }
6236 }
6237 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286238 RestoreStateForAttrib(0);
[email protected]38d139d2011-07-14 00:38:436239 }
[email protected]38d139d2011-07-14 00:38:436240 }
6241 return error::kNoError;
6242}
6243
[email protected]c6aef902012-02-14 03:31:426244error::Error GLES2DecoderImpl::HandleDrawArrays(
[email protected]ed9f9cd2013-02-27 21:12:356245 uint32 immediate_data_size, const cmds::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:436246 return DoDrawArrays("glDrawArrays",
6247 false,
[email protected]c6aef902012-02-14 03:31:426248 static_cast<GLenum>(c.mode),
6249 static_cast<GLint>(c.first),
6250 static_cast<GLsizei>(c.count),
6251 0);
6252}
6253
6254error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356255 uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156256 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516257 LOCAL_SET_GL_ERROR(
6258 GL_INVALID_OPERATION,
6259 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426260 return error::kNoError;
6261 }
[email protected]ad84a3a2012-06-08 21:42:436262 return DoDrawArrays("glDrawArraysIntancedANGLE",
6263 true,
[email protected]c6aef902012-02-14 03:31:426264 static_cast<GLenum>(c.mode),
6265 static_cast<GLint>(c.first),
6266 static_cast<GLsizei>(c.count),
6267 static_cast<GLsizei>(c.primcount));
6268}
6269
[email protected]ad84a3a2012-06-08 21:42:436270error::Error GLES2DecoderImpl::DoDrawElements(
6271 const char* function_name,
6272 bool instanced,
6273 GLenum mode,
6274 GLsizei count,
6275 GLenum type,
6276 int32 offset,
6277 GLsizei primcount) {
[email protected]a7266a92012-06-28 02:11:086278 if (ShouldDeferDraws())
6279 return error::kDeferCommandUntilLater;
[email protected]e259eb412012-10-13 05:47:246280 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516281 LOCAL_SET_GL_ERROR(
6282 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296283 return error::kNoError;
6284 }
6285
[email protected]8eee29c2010-04-29 03:38:296286 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516287 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296288 return error::kNoError;
6289 }
6290 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516291 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296292 return error::kNoError;
6293 }
[email protected]9438b012010-06-15 22:55:056294 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516295 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296296 return error::kNoError;
6297 }
[email protected]9438b012010-06-15 22:55:056298 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516299 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296300 return error::kNoError;
6301 }
[email protected]c6aef902012-02-14 03:31:426302 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516303 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426304 return error::kNoError;
6305 }
[email protected]8eee29c2010-04-29 03:38:296306
[email protected]ad84a3a2012-06-08 21:42:436307 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276308 return error::kNoError;
6309 }
6310
[email protected]c6aef902012-02-14 03:31:426311 if (count == 0 || (instanced && primcount == 0)) {
[email protected]6c788fb72010-08-26 02:16:316312 return error::kNoError;
6313 }
6314
[email protected]8eee29c2010-04-29 03:38:296315 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086316 Buffer* element_array_buffer =
6317 state_.vertex_attrib_manager->element_array_buffer();
6318
6319 if (!element_array_buffer->GetMaxValueForRange(
6320 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516321 LOCAL_SET_GL_ERROR(
6322 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296323 return error::kNoError;
6324 }
6325
[email protected]ad84a3a2012-06-08 21:42:436326 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206327 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516328 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206329 return error::kNoError;
6330 }
[email protected]c13e1da62011-09-09 21:48:306331 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436332 if (!SimulateAttrib0(
6333 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306334 return error::kNoError;
6335 }
[email protected]8fbedc02010-11-18 18:43:406336 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436337 if (SimulateFixedAttribs(
6338 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6339 primcount)) {
[email protected]e56131d22013-07-28 16:14:116340 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466341 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086342 // TODO(gman): Refactor to hide these details in BufferManager or
6343 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406344 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086345 bool used_client_side_array = false;
6346 if (element_array_buffer->IsClientSideArray()) {
6347 used_client_side_array = true;
6348 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6349 indices = element_array_buffer->GetRange(offset, 0);
6350 }
6351
[email protected]c6aef902012-02-14 03:31:426352 if (!instanced) {
6353 glDrawElements(mode, count, type, indices);
6354 } else {
6355 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6356 }
[email protected]17cfbe0e2013-03-07 01:26:086357
6358 if (used_client_side_array) {
6359 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6360 element_array_buffer->service_id());
6361 }
6362
[email protected]22e3f552012-03-13 01:54:196363 ProcessPendingQueries();
[email protected]8fbedc02010-11-18 18:43:406364 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546365 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:406366 }
6367 if (simulated_fixed_attribs) {
6368 RestoreStateForSimulatedFixedAttribs();
6369 }
[email protected]ba3176a2009-12-16 18:19:466370 }
[email protected]b1122982010-05-17 23:04:246371 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286372 RestoreStateForAttrib(0);
[email protected]b1122982010-05-17 23:04:246373 }
[email protected]96449d2c2009-11-25 00:01:326374 }
[email protected]f7a64ee2010-02-01 22:24:146375 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326376}
6377
[email protected]c6aef902012-02-14 03:31:426378error::Error GLES2DecoderImpl::HandleDrawElements(
[email protected]ed9f9cd2013-02-27 21:12:356379 uint32 immediate_data_size, const cmds::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:436380 return DoDrawElements("glDrawElements",
6381 false,
[email protected]c6aef902012-02-14 03:31:426382 static_cast<GLenum>(c.mode),
6383 static_cast<GLsizei>(c.count),
6384 static_cast<GLenum>(c.type),
6385 static_cast<int32>(c.index_offset),
6386 0);
6387}
6388
6389error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356390 uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156391 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516392 LOCAL_SET_GL_ERROR(
6393 GL_INVALID_OPERATION,
6394 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426395 return error::kNoError;
6396 }
[email protected]ad84a3a2012-06-08 21:42:436397 return DoDrawElements("glDrawElementsInstancedANGLE",
6398 true,
[email protected]c6aef902012-02-14 03:31:426399 static_cast<GLenum>(c.mode),
6400 static_cast<GLsizei>(c.count),
6401 static_cast<GLenum>(c.type),
6402 static_cast<int32>(c.index_offset),
6403 static_cast<GLsizei>(c.primcount));
6404}
6405
[email protected]269200b12010-11-18 22:53:066406GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236407 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6408 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076409 Buffer* buffer = GetBuffer(buffer_id);
6410 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036411 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516412 LOCAL_SET_GL_ERROR(
6413 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236414 } else {
[email protected]b10492f2013-03-08 05:24:076415 if (!buffer->GetMaxValueForRange(
6416 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036417 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516418 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066419 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436420 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236421 }
6422 }
6423 return max_vertex_accessed;
6424}
6425
[email protected]96449d2c2009-11-25 00:01:326426// Calls glShaderSource for the various versions of the ShaderSource command.
6427// Assumes that data / data_size points to a piece of memory that is in range
6428// of whatever context it came from (shared memory, immediate memory, bucket
6429// memory.)
[email protected]45bf5152010-02-12 00:11:316430error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036431 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576432 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426433 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6434 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316435 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326436 }
[email protected]45bf5152010-02-12 00:11:316437 // Note: We don't actually call glShaderSource here. We wait until
6438 // the call to glCompileShader.
[email protected]df37b9932013-03-08 05:21:426439 shader->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:146440 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326441}
6442
[email protected]f7a64ee2010-02-01 22:24:146443error::Error GLES2DecoderImpl::HandleShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356444 uint32 immediate_data_size, const cmds::ShaderSource& c) {
[email protected]96449d2c2009-11-25 00:01:326445 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316446 const char* data = GetSharedMemoryAs<const char*>(
[email protected]96449d2c2009-11-25 00:01:326447 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]ba3176a2009-12-16 18:19:466448 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146449 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326450 }
[email protected]ae51d192010-04-27 00:48:036451 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]96449d2c2009-11-25 00:01:326452}
6453
[email protected]558847a2010-03-24 07:02:546454error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
[email protected]ed9f9cd2013-02-27 21:12:356455 uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:546456 Bucket* bucket = GetBucket(c.data_bucket_id);
6457 if (!bucket || bucket->size() == 0) {
6458 return error::kInvalidArguments;
6459 }
6460 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036461 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546462 bucket->size() - 1);
6463}
6464
[email protected]ae51d192010-04-27 00:48:036465void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386466 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426467 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6468 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316469 return;
6470 }
[email protected]f57bb282010-11-12 00:51:346471 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186472 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426473 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456474 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416475 }
[email protected]de17df392010-04-23 21:09:416476
[email protected]7cd76fd2013-06-02 21:11:116477 program_manager()->DoCompileShader(shader, translator, feature_info_.get());
[email protected]45bf5152010-02-12 00:11:316478};
6479
[email protected]ddd968b82010-03-02 00:44:296480void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426481 GLuint shader_id, GLenum pname, GLint* params) {
6482 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6483 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296484 return;
6485 }
[email protected]8f1ccdac2010-05-19 21:01:486486 switch (pname) {
6487 case GL_SHADER_SOURCE_LENGTH:
[email protected]df37b9932013-03-08 05:21:426488 *params = shader->source() ? shader->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:486489 return;
6490 case GL_COMPILE_STATUS:
[email protected]df37b9932013-03-08 05:21:426491 *params = compile_shader_always_succeeds_ ? true : shader->IsValid();
[email protected]e5186162010-06-14 18:54:416492 return;
[email protected]8f1ccdac2010-05-19 21:01:486493 case GL_INFO_LOG_LENGTH:
[email protected]df37b9932013-03-08 05:21:426494 *params = shader->log_info() ? shader->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:416495 return;
[email protected]d6a53e42011-10-05 00:09:366496 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]df37b9932013-03-08 05:21:426497 *params = shader->translated_source() ?
6498 shader->translated_source()->size() + 1 : 0;
[email protected]d6a53e42011-10-05 00:09:366499 return;
[email protected]8f1ccdac2010-05-19 21:01:486500 default:
6501 break;
[email protected]ddd968b82010-03-02 00:44:296502 }
[email protected]df37b9932013-03-08 05:21:426503 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296504}
6505
[email protected]ae51d192010-04-27 00:48:036506error::Error GLES2DecoderImpl::HandleGetShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356507 uint32 immediate_data_size, const cmds::GetShaderSource& c) {
[email protected]df37b9932013-03-08 05:21:426508 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036509 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6510 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426511 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
6512 if (!shader || !shader->source()) {
[email protected]8eee29c2010-04-29 03:38:296513 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296514 return error::kNoError;
6515 }
[email protected]df37b9932013-03-08 05:21:426516 bucket->SetFromString(shader->source()->c_str());
[email protected]ae51d192010-04-27 00:48:036517 return error::kNoError;
6518}
6519
[email protected]d6a53e42011-10-05 00:09:366520error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6521 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:356522 const cmds::GetTranslatedShaderSourceANGLE& c) {
[email protected]df37b9932013-03-08 05:21:426523 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366524 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6525 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426526 Shader* shader = GetShaderInfoNotProgram(
6527 shader_id, "glTranslatedGetShaderSourceANGLE");
6528 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366529 bucket->SetSize(0);
6530 return error::kNoError;
6531 }
6532
[email protected]df37b9932013-03-08 05:21:426533 bucket->SetFromString(shader->translated_source() ?
6534 shader->translated_source()->c_str() : NULL);
[email protected]d6a53e42011-10-05 00:09:366535 return error::kNoError;
6536}
6537
[email protected]ae51d192010-04-27 00:48:036538error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356539 uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426540 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586541 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6542 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426543 Program* program = GetProgramInfoNotShader(
6544 program_id, "glGetProgramInfoLog");
6545 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466546 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036547 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316548 }
[email protected]df37b9932013-03-08 05:21:426549 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036550 return error::kNoError;
6551}
6552
6553error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356554 uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426555 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586556 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6557 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426558 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
6559 if (!shader || !shader->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466560 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036561 return error::kNoError;
6562 }
[email protected]df37b9932013-03-08 05:21:426563 bucket->SetFromString(shader->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036564 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326565}
6566
[email protected]d058bca2012-11-26 10:27:266567bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6568 return state_.GetEnabled(cap);
6569}
6570
[email protected]1958e0e2010-04-22 05:17:156571bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:216572 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106573 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156574}
6575
6576bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356577 const Framebuffer* framebuffer =
6578 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106579 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156580}
6581
6582bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366583 // IsProgram is true for programs as soon as they are created, until they are
6584 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:356585 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:106586 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156587}
6588
6589bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356590 const Renderbuffer* renderbuffer =
6591 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106592 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156593}
6594
6595bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366596 // IsShader is true for shaders as soon as they are created, until they
6597 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:356598 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:106599 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156600}
6601
6602bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:496603 const TextureRef* texture_ref = GetTexture(client_id);
6604 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:036605}
6606
6607void GLES2DecoderImpl::DoAttachShader(
6608 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426609 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586610 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:426611 if (!program) {
[email protected]ae51d192010-04-27 00:48:036612 return;
[email protected]1958e0e2010-04-22 05:17:156613 }
[email protected]df37b9932013-03-08 05:21:426614 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
6615 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036616 return;
6617 }
[email protected]df37b9932013-03-08 05:21:426618 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516619 LOCAL_SET_GL_ERROR(
6620 GL_INVALID_OPERATION,
6621 "glAttachShader",
6622 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:316623 return;
6624 }
[email protected]df37b9932013-03-08 05:21:426625 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036626}
6627
6628void GLES2DecoderImpl::DoDetachShader(
6629 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426630 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586631 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:426632 if (!program) {
[email protected]ae51d192010-04-27 00:48:036633 return;
6634 }
[email protected]df37b9932013-03-08 05:21:426635 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
6636 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036637 return;
6638 }
[email protected]df37b9932013-03-08 05:21:426639 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516640 LOCAL_SET_GL_ERROR(
6641 GL_INVALID_OPERATION,
6642 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:226643 return;
6644 }
[email protected]df37b9932013-03-08 05:21:426645 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036646}
6647
6648void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:426649 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586650 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:426651 if (!program) {
[email protected]ae51d192010-04-27 00:48:036652 return;
6653 }
[email protected]df37b9932013-03-08 05:21:426654 program->Validate();
[email protected]1958e0e2010-04-22 05:17:156655}
6656
[email protected]ac77603c72013-03-08 13:52:066657void GLES2DecoderImpl::GetVertexAttribHelper(
6658 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:246659 switch (pname) {
6660 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:066661 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:246662 if (buffer && !buffer->IsDeleted()) {
6663 GLuint client_id;
6664 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6665 *params = client_id;
6666 }
6667 break;
6668 }
6669 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:066670 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:246671 break;
6672 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:066673 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:246674 break;
6675 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:066676 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:246677 break;
6678 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:066679 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:246680 break;
6681 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:066682 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:246683 break;
[email protected]c6aef902012-02-14 03:31:426684 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:066685 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:426686 break;
[email protected]ac77603c72013-03-08 13:52:066687 default:
6688 NOTREACHED();
6689 break;
6690 }
6691}
6692
6693void GLES2DecoderImpl::DoGetVertexAttribfv(
6694 GLuint index, GLenum pname, GLfloat* params) {
6695 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6696 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516697 LOCAL_SET_GL_ERROR(
6698 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066699 return;
6700 }
6701 switch (pname) {
6702 case GL_CURRENT_VERTEX_ATTRIB: {
6703 const Vec4& value = state_.attrib_values[index];
6704 params[0] = value.v[0];
6705 params[1] = value.v[1];
6706 params[2] = value.v[2];
6707 params[3] = value.v[3];
6708 break;
6709 }
6710 default: {
6711 GLint value = 0;
6712 GetVertexAttribHelper(attrib, pname, &value);
6713 *params = static_cast<GLfloat>(value);
6714 break;
6715 }
6716 }
6717}
6718
6719void GLES2DecoderImpl::DoGetVertexAttribiv(
6720 GLuint index, GLenum pname, GLint* params) {
6721 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6722 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516723 LOCAL_SET_GL_ERROR(
6724 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066725 return;
6726 }
6727 switch (pname) {
[email protected]af6380962012-11-29 23:24:136728 case GL_CURRENT_VERTEX_ATTRIB: {
6729 const Vec4& value = state_.attrib_values[index];
6730 params[0] = static_cast<GLint>(value.v[0]);
6731 params[1] = static_cast<GLint>(value.v[1]);
6732 params[2] = static_cast<GLint>(value.v[2]);
6733 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:246734 break;
[email protected]af6380962012-11-29 23:24:136735 }
[email protected]b1122982010-05-17 23:04:246736 default:
[email protected]ac77603c72013-03-08 13:52:066737 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:246738 break;
6739 }
6740}
6741
[email protected]af6380962012-11-29 23:24:136742bool GLES2DecoderImpl::SetVertexAttribValue(
6743 const char* function_name, GLuint index, const GLfloat* value) {
6744 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:516745 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:136746 return false;
[email protected]b1122982010-05-17 23:04:246747 }
[email protected]af6380962012-11-29 23:24:136748 Vec4& v = state_.attrib_values[index];
6749 v.v[0] = value[0];
6750 v.v[1] = value[1];
6751 v.v[2] = value[2];
6752 v.v[3] = value[3];
6753 return true;
6754}
6755
6756void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
6757 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
6758 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
6759 glVertexAttrib1f(index, v0);
6760 }
[email protected]b1122982010-05-17 23:04:246761}
6762
6763void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:136764 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
6765 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
6766 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:246767 }
[email protected]b1122982010-05-17 23:04:246768}
6769
6770void GLES2DecoderImpl::DoVertexAttrib3f(
6771 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:136772 GLfloat v[4] = { v0, v1, v2, 1.0f, };
6773 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
6774 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:246775 }
[email protected]b1122982010-05-17 23:04:246776}
6777
6778void GLES2DecoderImpl::DoVertexAttrib4f(
6779 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:136780 GLfloat v[4] = { v0, v1, v2, v3, };
6781 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
6782 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:246783 }
[email protected]b1122982010-05-17 23:04:246784}
6785
6786void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136787 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
6788 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
6789 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:246790 }
[email protected]b1122982010-05-17 23:04:246791}
6792
6793void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136794 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
6795 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
6796 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:246797 }
[email protected]b1122982010-05-17 23:04:246798}
6799
6800void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136801 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
6802 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
6803 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:246804 }
[email protected]b1122982010-05-17 23:04:246805}
6806
6807void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:136808 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
6809 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:246810 }
[email protected]b1122982010-05-17 23:04:246811}
6812
[email protected]f7a64ee2010-02-01 22:24:146813error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]ed9f9cd2013-02-27 21:12:356814 uint32 immediate_data_size, const cmds::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:466815
[email protected]7cd76fd2013-06-02 21:11:116816 if (!state_.bound_array_buffer.get() ||
6817 state_.bound_array_buffer->IsDeleted()) {
6818 if (state_.vertex_attrib_manager.get() ==
6819 default_vertex_attrib_manager_.get()) {
[email protected]ab09b612013-03-11 22:11:516820 LOCAL_SET_GL_ERROR(
6821 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:466822 return error::kNoError;
6823 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:516824 LOCAL_SET_GL_ERROR(
6825 GL_INVALID_VALUE,
6826 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:466827 return error::kNoError;
6828 }
[email protected]96449d2c2009-11-25 00:01:326829 }
[email protected]8eee29c2010-04-29 03:38:296830
6831 GLuint indx = c.indx;
6832 GLint size = c.size;
6833 GLenum type = c.type;
6834 GLboolean normalized = c.normalized;
6835 GLsizei stride = c.stride;
6836 GLsizei offset = c.offset;
6837 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:056838 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516839 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:296840 return error::kNoError;
6841 }
[email protected]9438b012010-06-15 22:55:056842 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:516843 LOCAL_SET_GL_ERROR(
6844 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:296845 return error::kNoError;
6846 }
6847 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516848 LOCAL_SET_GL_ERROR(
6849 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:296850 return error::kNoError;
6851 }
6852 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:516853 LOCAL_SET_GL_ERROR(
6854 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:296855 return error::kNoError;
6856 }
6857 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:516858 LOCAL_SET_GL_ERROR(
6859 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:296860 return error::kNoError;
6861 }
6862 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516863 LOCAL_SET_GL_ERROR(
6864 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296865 return error::kNoError;
6866 }
6867 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:316868 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]8eee29c2010-04-29 03:38:296869 if (offset % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:516870 LOCAL_SET_GL_ERROR(
6871 GL_INVALID_OPERATION,
6872 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:316873 return error::kNoError;
6874 }
6875 if (stride % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:516876 LOCAL_SET_GL_ERROR(
6877 GL_INVALID_OPERATION,
6878 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:296879 return error::kNoError;
6880 }
[email protected]7cd76fd2013-06-02 21:11:116881 state_.vertex_attrib_manager
6882 ->SetAttribInfo(indx,
6883 state_.bound_array_buffer.get(),
6884 size,
6885 type,
6886 normalized,
6887 stride,
6888 stride != 0 ? stride : component_size * size,
6889 offset);
[email protected]8fbedc02010-11-18 18:43:406890 if (type != GL_FIXED) {
6891 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
6892 }
[email protected]f7a64ee2010-02-01 22:24:146893 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326894}
6895
[email protected]43410e92012-04-20 17:06:286896void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
6897 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:246898 state_.viewport_x = x;
6899 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:026900 state_.viewport_width = std::min(width, viewport_max_width_);
6901 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:286902 glViewport(x, y, width, height);
6903}
6904
[email protected]c6aef902012-02-14 03:31:426905error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356906 uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156907 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516908 LOCAL_SET_GL_ERROR(
6909 GL_INVALID_OPERATION,
6910 "glVertexAttribDivisorANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426911 }
6912 GLuint index = c.index;
6913 GLuint divisor = c.divisor;
6914 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:516915 LOCAL_SET_GL_ERROR(
6916 GL_INVALID_VALUE,
6917 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:426918 return error::kNoError;
6919 }
6920
[email protected]e259eb412012-10-13 05:47:246921 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:426922 index,
6923 divisor);
6924 glVertexAttribDivisorANGLE(index, divisor);
6925 return error::kNoError;
6926}
6927
[email protected]5a36dc132013-07-23 23:17:556928void GLES2DecoderImpl::FinishReadPixels(
6929 const cmds::ReadPixels& c,
6930 GLuint buffer) {
6931 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
6932 GLsizei width = c.width;
6933 GLsizei height = c.height;
6934 GLenum format = c.format;
6935 GLenum type = c.type;
6936 typedef cmds::ReadPixels::Result Result;
6937 uint32 pixels_size;
6938 Result* result = NULL;
6939 if (c.result_shm_id != 0) {
6940 result = GetSharedMemoryAs<Result*>(
6941 c.result_shm_id, c.result_shm_offset, sizeof(*result));
6942 if (!result) {
6943 if (buffer != 0) {
6944 glDeleteBuffersARB(1, &buffer);
6945 }
6946 return;
6947 }
6948 }
6949 GLES2Util::ComputeImageDataSizes(
6950 width, height, format, type, state_.pack_alignment, &pixels_size,
6951 NULL, NULL);
6952 void* pixels = GetSharedMemoryAs<void*>(
6953 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
6954 if (!pixels) {
6955 if (buffer != 0) {
6956 glDeleteBuffersARB(1, &buffer);
6957 }
6958 return;
6959 }
6960
6961 if (buffer != 0) {
6962 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:336963 void* data;
6964 if (features().map_buffer_range) {
6965 data = glMapBufferRange(
6966 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
6967 } else {
6968 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
6969 }
[email protected]5a36dc132013-07-23 23:17:556970 memcpy(pixels, data, pixels_size);
6971 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
6972 // have to restore the state.
6973 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
6974 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
6975 glDeleteBuffersARB(1, &buffer);
6976 }
6977
6978 if (result != NULL) {
6979 *result = true;
6980 }
6981
6982 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
6983 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
6984 if ((channels_exist & 0x0008) == 0 &&
6985 workarounds().clear_alpha_in_readpixels) {
6986 // Set the alpha to 255 because some drivers are buggy in this regard.
6987 uint32 temp_size;
6988
6989 uint32 unpadded_row_size;
6990 uint32 padded_row_size;
6991 if (!GLES2Util::ComputeImageDataSizes(
6992 width, 2, format, type, state_.pack_alignment, &temp_size,
6993 &unpadded_row_size, &padded_row_size)) {
6994 return;
6995 }
6996 // NOTE: Assumes the type is GL_UNSIGNED_BYTE which was true at the time
6997 // of this implementation.
6998 if (type != GL_UNSIGNED_BYTE) {
6999 return;
7000 }
7001 switch (format) {
7002 case GL_RGBA:
7003 case GL_BGRA_EXT:
7004 case GL_ALPHA: {
7005 int offset = (format == GL_ALPHA) ? 0 : 3;
7006 int step = (format == GL_ALPHA) ? 1 : 4;
7007 uint8* dst = static_cast<uint8*>(pixels) + offset;
7008 for (GLint yy = 0; yy < height; ++yy) {
7009 uint8* end = dst + unpadded_row_size;
7010 for (uint8* d = dst; d < end; d += step) {
7011 *d = 255;
7012 }
7013 dst += padded_row_size;
7014 }
7015 break;
7016 }
7017 default:
7018 break;
7019 }
7020 }
7021}
7022
7023
[email protected]f7a64ee2010-02-01 22:24:147024error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]ed9f9cd2013-02-27 21:12:357025 uint32 immediate_data_size, const cmds::ReadPixels& c) {
[email protected]09e17272012-11-30 10:30:447026 if (ShouldDeferReads())
7027 return error::kDeferCommandUntilLater;
[email protected]612d2f82009-12-08 20:49:317028 GLint x = c.x;
7029 GLint y = c.y;
7030 GLsizei width = c.width;
7031 GLsizei height = c.height;
7032 GLenum format = c.format;
7033 GLenum type = c.type;
[email protected]5a36dc132013-07-23 23:17:557034 GLboolean async = c.async;
[email protected]57f223832010-03-19 01:57:567035 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517036 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567037 return error::kNoError;
7038 }
[email protected]ed9f9cd2013-02-27 21:12:357039 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187040 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347041 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247042 width, height, format, type, state_.pack_alignment, &pixels_size,
7043 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187044 return error::kOutOfBounds;
7045 }
[email protected]612d2f82009-12-08 20:49:317046 void* pixels = GetSharedMemoryAs<void*>(
7047 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107048 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147049 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467050 }
[email protected]de43f082013-04-02 01:16:107051 Result* result = NULL;
7052 if (c.result_shm_id != 0) {
7053 result = GetSharedMemoryAs<Result*>(
7054 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7055 if (!result) {
7056 return error::kOutOfBounds;
7057 }
7058 }
[email protected]a51788e2010-02-24 21:54:257059
[email protected]9438b012010-06-15 22:55:057060 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517061 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297062 return error::kNoError;
7063 }
[email protected]9438b012010-06-15 22:55:057064 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517065 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127066 return error::kNoError;
7067 }
[email protected]57f223832010-03-19 01:57:567068 if (width == 0 || height == 0) {
7069 return error::kNoError;
7070 }
7071
[email protected]57f223832010-03-19 01:57:567072 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307073 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567074
[email protected]3aad1a32012-09-07 20:54:477075 int32 max_x;
7076 int32 max_y;
7077 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517078 LOCAL_SET_GL_ERROR(
7079 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147080 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317081 }
[email protected]57f223832010-03-19 01:57:567082
[email protected]0d6bfdc2011-11-02 01:32:207083 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7084 return error::kNoError;
7085 }
7086
[email protected]ab09b612013-03-11 22:11:517087 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixel");
[email protected]a0b78dc2011-11-11 10:43:107088
7089 ScopedResolvedFrameBufferBinder binder(this, false, true);
7090
[email protected]d37231fa2010-04-09 21:16:027091 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567092 // The user requested an out of range area. Get the results 1 line
7093 // at a time.
7094 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347095 uint32 unpadded_row_size;
7096 uint32 padded_row_size;
7097 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247098 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347099 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517100 LOCAL_SET_GL_ERROR(
7101 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567102 return error::kNoError;
7103 }
7104
7105 GLint dest_x_offset = std::max(-x, 0);
7106 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347107 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247108 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
7109 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517110 LOCAL_SET_GL_ERROR(
7111 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567112 return error::kNoError;
7113 }
7114
7115 // Copy each row into the larger dest rect.
7116 int8* dst = static_cast<int8*>(pixels);
7117 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027118 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567119 GLint read_width = read_end_x - read_x;
7120 for (GLint yy = 0; yy < height; ++yy) {
7121 GLint ry = y + yy;
7122
7123 // Clear the row.
7124 memset(dst, 0, unpadded_row_size);
7125
7126 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027127 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567128 glReadPixels(
7129 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7130 }
7131 dst += padded_row_size;
7132 }
7133 } else {
[email protected]5a36dc132013-07-23 23:17:557134 if (async && features().use_async_readpixels) {
7135 GLuint buffer;
7136 glGenBuffersARB(1, &buffer);
7137 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
7138 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ);
7139 GLenum error = glGetError();
7140 if (error == GL_NO_ERROR) {
7141 glReadPixels(x, y, width, height, format, type, 0);
7142 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7143 new FenceCallback()));
7144 WaitForReadPixels(base::Bind(
7145 &GLES2DecoderImpl::FinishReadPixels,
7146 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7147 <GLES2DecoderImpl>(this),
7148 c, buffer));
7149 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7150 return error::kNoError;
7151 }
7152 }
[email protected]57f223832010-03-19 01:57:567153 glReadPixels(x, y, width, height, format, type, pixels);
7154 }
[email protected]ab09b612013-03-11 22:11:517155 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257156 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107157 if (result != NULL) {
7158 *result = true;
7159 }
[email protected]5a36dc132013-07-23 23:17:557160 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257161 }
[email protected]4848b9f82011-03-10 18:37:567162
[email protected]f7a64ee2010-02-01 22:24:147163 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327164}
7165
[email protected]f7a64ee2010-02-01 22:24:147166error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]ed9f9cd2013-02-27 21:12:357167 uint32 immediate_data_size, const cmds::PixelStorei& c) {
[email protected]b9849abf2009-11-25 19:13:197168 GLenum pname = c.pname;
7169 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057170 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517171 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127172 return error::kNoError;
7173 }
[email protected]222471d2011-11-30 18:06:397174 switch (pname) {
7175 case GL_PACK_ALIGNMENT:
7176 case GL_UNPACK_ALIGNMENT:
7177 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517178 LOCAL_SET_GL_ERROR(
7179 GL_INVALID_VALUE, "glPixelStore", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397180 return error::kNoError;
7181 }
[email protected]164d6d52012-05-05 00:55:037182 break;
[email protected]0a1e9ad2012-05-04 21:13:037183 case GL_UNPACK_FLIP_Y_CHROMIUM:
7184 unpack_flip_y_ = (param != 0);
7185 return error::kNoError;
7186 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7187 unpack_premultiply_alpha_ = (param != 0);
7188 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177189 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7190 unpack_unpremultiply_alpha_ = (param != 0);
7191 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397192 default:
7193 break;
[email protected]b9849abf2009-11-25 19:13:197194 }
7195 glPixelStorei(pname, param);
7196 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437197 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247198 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437199 break;
7200 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427201 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437202 break;
7203 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247204 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437205 break;
7206 default:
7207 // Validation should have prevented us from getting here.
7208 NOTREACHED();
7209 break;
[email protected]b9849abf2009-11-25 19:13:197210 }
[email protected]f7a64ee2010-02-01 22:24:147211 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197212}
7213
[email protected]1c75a3702011-11-11 14:15:287214error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:357215 uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:387216 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]6f5fac9d12012-06-26 21:02:457217 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) {
[email protected]ab09b612013-03-11 22:11:517218 LOCAL_SET_GL_ERROR(
7219 GL_INVALID_OPERATION,
7220 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:287221 return error::kNoError;
7222 }
[email protected]8f9b8dd2013-09-12 18:05:137223 bool is_tracing;
7224 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
7225 &is_tracing);
7226 if (is_tracing) {
7227 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
7228 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
7229 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
7230 is_offscreen ? offscreen_size_ : surface_->GetSize());
7231 }
[email protected]7794d512012-04-17 20:36:497232 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:287233 return error::kNoError;
[email protected]7794d512012-04-17 20:36:497234 } else {
7235 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:287236 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:497237 }
[email protected]1c75a3702011-11-11 14:15:287238}
7239
[email protected]558847a2010-03-24 07:02:547240error::Error GLES2DecoderImpl::GetAttribLocationHelper(
7241 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7242 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577243 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517244 LOCAL_SET_GL_ERROR(
7245 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577246 return error::kNoError;
7247 }
[email protected]df37b9932013-03-08 05:21:427248 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587249 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:427250 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147251 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197252 }
[email protected]df37b9932013-03-08 05:21:427253 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517254 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437255 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257256 return error::kNoError;
7257 }
[email protected]b9849abf2009-11-25 19:13:197258 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547259 location_shm_id, location_shm_offset, sizeof(GLint));
7260 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147261 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197262 }
[email protected]558847a2010-03-24 07:02:547263 // Require the client to init this incase the context is lost and we are no
7264 // longer executing commands.
7265 if (*location != -1) {
7266 return error::kGenericError;
7267 }
[email protected]df37b9932013-03-08 05:21:427268 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147269 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197270}
7271
[email protected]558847a2010-03-24 07:02:547272error::Error GLES2DecoderImpl::HandleGetAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:357273 uint32 immediate_data_size, const cmds::GetAttribLocation& c) {
[email protected]558847a2010-03-24 07:02:547274 uint32 name_size = c.data_size;
7275 const char* name = GetSharedMemoryAs<const char*>(
7276 c.name_shm_id, c.name_shm_offset, name_size);
7277 if (!name) {
7278 return error::kOutOfBounds;
7279 }
7280 String name_str(name, name_size);
7281 return GetAttribLocationHelper(
7282 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7283}
7284
[email protected]558847a2010-03-24 07:02:547285error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357286 uint32 immediate_data_size, const cmds::GetAttribLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547287 Bucket* bucket = GetBucket(c.name_bucket_id);
7288 if (!bucket) {
7289 return error::kInvalidArguments;
7290 }
7291 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187292 if (!bucket->GetAsString(&name_str)) {
7293 return error::kInvalidArguments;
7294 }
[email protected]558847a2010-03-24 07:02:547295 return GetAttribLocationHelper(
7296 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7297}
7298
7299error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7300 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7301 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577302 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517303 LOCAL_SET_GL_ERROR(
7304 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577305 return error::kNoError;
7306 }
[email protected]df37b9932013-03-08 05:21:427307 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587308 client_id, "glUniformLocation");
[email protected]df37b9932013-03-08 05:21:427309 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147310 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197311 }
[email protected]df37b9932013-03-08 05:21:427312 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517313 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437314 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257315 return error::kNoError;
7316 }
[email protected]b9849abf2009-11-25 19:13:197317 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547318 location_shm_id, location_shm_offset, sizeof(GLint));
7319 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147320 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197321 }
[email protected]558847a2010-03-24 07:02:547322 // Require the client to init this incase the context is lost an we are no
7323 // longer executing commands.
7324 if (*location != -1) {
7325 return error::kGenericError;
7326 }
[email protected]df37b9932013-03-08 05:21:427327 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147328 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197329}
7330
[email protected]f7a64ee2010-02-01 22:24:147331error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]ed9f9cd2013-02-27 21:12:357332 uint32 immediate_data_size, const cmds::GetUniformLocation& c) {
[email protected]b9849abf2009-11-25 19:13:197333 uint32 name_size = c.data_size;
7334 const char* name = GetSharedMemoryAs<const char*>(
7335 c.name_shm_id, c.name_shm_offset, name_size);
[email protected]558847a2010-03-24 07:02:547336 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147337 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197338 }
7339 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547340 return GetUniformLocationHelper(
7341 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197342}
7343
[email protected]558847a2010-03-24 07:02:547344error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357345 uint32 immediate_data_size, const cmds::GetUniformLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547346 Bucket* bucket = GetBucket(c.name_bucket_id);
7347 if (!bucket) {
7348 return error::kInvalidArguments;
7349 }
7350 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187351 if (!bucket->GetAsString(&name_str)) {
7352 return error::kInvalidArguments;
7353 }
[email protected]558847a2010-03-24 07:02:547354 return GetUniformLocationHelper(
7355 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197356}
7357
[email protected]ddd968b82010-03-02 00:44:297358error::Error GLES2DecoderImpl::HandleGetString(
[email protected]ed9f9cd2013-02-27 21:12:357359 uint32 immediate_data_size, const cmds::GetString& c) {
[email protected]ddd968b82010-03-02 00:44:297360 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057361 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517362 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297363 return error::kNoError;
7364 }
[email protected]959e9072013-09-20 16:58:387365 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:047366 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157367 switch (name) {
7368 case GL_VERSION:
7369 str = "OpenGL ES 2.0 Chromium";
7370 break;
7371 case GL_SHADING_LANGUAGE_VERSION:
7372 str = "OpenGL ES GLSL ES 1.0 Chromium";
7373 break;
[email protected]32939602012-05-09 06:25:167374 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:167375 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:387376 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
7377 // They are used by WEBGL_debug_renderer_info.
7378 if (!force_webgl_glsl_validation_)
7379 str = "Chromium";
[email protected]32939602012-05-09 06:25:167380 break;
[email protected]1958e0e2010-04-22 05:17:157381 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047382 {
[email protected]70dc60932013-06-04 03:33:497383 // For WebGL contexts, strip out the OES derivatives and
7384 // EXT frag depth extensions if they have not been enabled.
7385 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:047386 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:497387 if (!derivatives_explicitly_enabled_) {
7388 size_t offset = extensions.find(kOESDerivativeExtension);
7389 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097390 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:497391 std::string());
7392 }
7393 }
7394 if (!frag_depth_explicitly_enabled_) {
7395 size_t offset = extensions.find(kEXTFragDepthExtension);
7396 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097397 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:497398 std::string());
7399 }
[email protected]f0d74742011-10-03 16:31:047400 }
[email protected]aff39ac82013-06-08 04:53:137401 if (!draw_buffers_explicitly_enabled_) {
7402 size_t offset = extensions.find(kEXTDrawBuffersExtension);
7403 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097404 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:137405 std::string());
7406 }
7407 }
[email protected]f0d74742011-10-03 16:31:047408 } else {
[email protected]6f5fac9d12012-06-26 21:02:457409 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047410 }
[email protected]6f5fac9d12012-06-26 21:02:457411 std::string surface_extensions = surface_->GetExtensions();
7412 if (!surface_extensions.empty())
7413 extensions += " " + surface_extensions;
7414 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047415 }
[email protected]1958e0e2010-04-22 05:17:157416 break;
7417 default:
[email protected]1958e0e2010-04-22 05:17:157418 break;
7419 }
[email protected]ddd968b82010-03-02 00:44:297420 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157421 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297422 return error::kNoError;
7423}
7424
[email protected]0c86dbf2010-03-05 08:14:117425error::Error GLES2DecoderImpl::HandleBufferData(
[email protected]ed9f9cd2013-02-27 21:12:357426 uint32 immediate_data_size, const cmds::BufferData& c) {
[email protected]0c86dbf2010-03-05 08:14:117427 GLenum target = static_cast<GLenum>(c.target);
7428 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7429 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7430 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7431 GLenum usage = static_cast<GLenum>(c.usage);
7432 const void* data = NULL;
7433 if (data_shm_id != 0 || data_shm_offset != 0) {
7434 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7435 if (!data) {
7436 return error::kOutOfBounds;
7437 }
7438 }
[email protected]0fbba3732013-07-17 15:40:137439 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147440 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197441}
7442
[email protected]0c86dbf2010-03-05 08:14:117443void GLES2DecoderImpl::DoBufferSubData(
7444 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:137445 // Just delegate it. Some validation is actually done before this.
7446 buffer_manager()->ValidateAndDoBufferSubData(
7447 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:197448}
7449
[email protected]0d6bfdc2011-11-02 01:32:207450bool GLES2DecoderImpl::ClearLevel(
7451 unsigned service_id,
7452 unsigned bind_target,
7453 unsigned target,
7454 int level,
7455 unsigned format,
7456 unsigned type,
7457 int width,
[email protected]4502e6492011-12-14 19:39:157458 int height,
7459 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007460 uint32 channels = GLES2Util::GetChannelsForFormat(format);
7461 if (IsAngle() && (channels & GLES2Util::kDepth) != 0) {
7462 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7463 // on depth formats.
7464 GLuint fb = 0;
7465 glGenFramebuffersEXT(1, &fb);
7466 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7467
7468 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7469 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7470 GL_DEPTH_ATTACHMENT;
7471
7472 glFramebufferTexture2DEXT(
7473 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7474 // ANGLE promises a depth only attachment ok.
7475 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7476 GL_FRAMEBUFFER_COMPLETE) {
7477 return false;
7478 }
7479 glClearStencil(0);
7480 glStencilMask(-1);
7481 glClearDepth(1.0f);
7482 glDepthMask(true);
7483 glDisable(GL_SCISSOR_TEST);
7484 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7485
7486 RestoreClearState();
7487
7488 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:357489 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:007490 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7491 GLuint fb_service_id =
7492 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7493 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7494 return true;
7495 }
7496
[email protected]45d15a62012-04-18 14:33:177497 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7498
7499 uint32 size;
7500 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:347501 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247502 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:177503 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:207504 return false;
7505 }
[email protected]45d15a62012-04-18 14:33:177506
[email protected]a5d3dad2012-05-26 04:34:447507 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7508
[email protected]45d15a62012-04-18 14:33:177509 int tile_height;
7510
7511 if (size > kMaxZeroSize) {
7512 if (kMaxZeroSize < padded_row_size) {
7513 // That'd be an awfully large texture.
7514 return false;
7515 }
7516 // We should never have a large total size with a zero row size.
7517 DCHECK_GT(padded_row_size, 0U);
7518 tile_height = kMaxZeroSize / padded_row_size;
7519 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247520 width, tile_height, format, type, state_.unpack_alignment, &size,
7521 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:177522 return false;
7523 }
[email protected]4502e6492011-12-14 19:39:157524 } else {
[email protected]45d15a62012-04-18 14:33:177525 tile_height = height;
7526 }
7527
7528 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:557529 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:177530 memset(zero.get(), 0, size);
7531 glBindTexture(bind_target, service_id);
7532
7533 GLint y = 0;
7534 while (y < height) {
7535 GLint h = y + tile_height > height ? height - y : tile_height;
7536 if (is_texture_immutable || h != height) {
7537 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7538 } else {
[email protected]8f1d2aa2013-05-10 23:45:387539 glTexImage2D(
[email protected]45d15a62012-04-18 14:33:177540 target, level, format, width, h, 0, format, type, zero.get());
7541 }
7542 y += tile_height;
[email protected]4502e6492011-12-14 19:39:157543 }
[email protected]c986af502013-08-14 01:04:447544 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
7545 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:077546 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:207547 return true;
7548}
7549
[email protected]ad84a3a2012-06-08 21:42:437550namespace {
7551
7552const int kS3TCBlockWidth = 4;
7553const int kS3TCBlockHeight = 4;
7554const int kS3TCDXT1BlockSize = 8;
7555const int kS3TCDXT3AndDXT5BlockSize = 16;
[email protected]2d3765b2012-10-03 00:31:077556const int kETC1BlockWidth = 4;
7557const int kETC1BlockHeight = 4;
7558const int kETC1BlockSize = 8;
[email protected]ad84a3a2012-06-08 21:42:437559
7560bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:517561 return (size == 1) ||
7562 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:437563}
7564
7565} // anonymous namespace.
7566
7567bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7568 const char* function_name,
7569 GLsizei width, GLsizei height, GLenum format, size_t size) {
7570 unsigned int bytes_required = 0;
7571
7572 switch (format) {
7573 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7574 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: {
7575 int num_blocks_across =
7576 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7577 int num_blocks_down =
7578 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7579 int num_blocks = num_blocks_across * num_blocks_down;
7580 bytes_required = num_blocks * kS3TCDXT1BlockSize;
7581 break;
7582 }
7583 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7584 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7585 int num_blocks_across =
7586 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7587 int num_blocks_down =
7588 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7589 int num_blocks = num_blocks_across * num_blocks_down;
7590 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
7591 break;
7592 }
[email protected]2d3765b2012-10-03 00:31:077593 case GL_ETC1_RGB8_OES: {
7594 int num_blocks_across =
7595 (width + kETC1BlockWidth - 1) / kETC1BlockWidth;
7596 int num_blocks_down =
7597 (height + kETC1BlockHeight - 1) / kETC1BlockHeight;
7598 int num_blocks = num_blocks_across * num_blocks_down;
7599 bytes_required = num_blocks * kETC1BlockSize;
7600 break;
7601 }
[email protected]ad84a3a2012-06-08 21:42:437602 default:
[email protected]ab09b612013-03-11 22:11:517603 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:437604 return false;
7605 }
7606
7607 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:517608 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437609 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
7610 return false;
7611 }
7612
7613 return true;
7614}
7615
7616bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
7617 const char* function_name,
7618 GLint level, GLsizei width, GLsizei height, GLenum format) {
7619 switch (format) {
7620 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7621 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7622 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7623 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7624 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:517625 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437626 GL_INVALID_OPERATION, function_name,
7627 "width or height invalid for level");
7628 return false;
7629 }
7630 return true;
7631 }
[email protected]2d3765b2012-10-03 00:31:077632 case GL_ETC1_RGB8_OES:
7633 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:517634 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077635 GL_INVALID_OPERATION, function_name,
7636 "width or height invalid for level");
7637 return false;
7638 }
7639 return true;
[email protected]ad84a3a2012-06-08 21:42:437640 default:
7641 return false;
7642 }
7643}
7644
7645bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
7646 const char* function_name,
7647 GLenum target, GLint level, GLint xoffset, GLint yoffset,
7648 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:357649 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:437650 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:517651 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437652 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
7653 return false;
7654 }
7655
7656 switch (format) {
7657 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7658 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7659 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7660 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7661 const int kBlockWidth = 4;
7662 const int kBlockHeight = 4;
7663 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:517664 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437665 GL_INVALID_OPERATION, function_name,
7666 "xoffset or yoffset not multiple of 4");
7667 return false;
7668 }
7669 GLsizei tex_width = 0;
7670 GLsizei tex_height = 0;
7671 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
7672 width - xoffset > tex_width ||
7673 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:517674 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437675 GL_INVALID_OPERATION, function_name, "dimensions out of range");
7676 return false;
7677 }
7678 return ValidateCompressedTexDimensions(
7679 function_name, level, width, height, format);
7680 }
[email protected]2d3765b2012-10-03 00:31:077681 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:517682 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077683 GL_INVALID_OPERATION, function_name,
7684 "TexsubImage2d not supported for ECT1_RGB8_OES textures");
7685 return false;
7686 }
[email protected]ad84a3a2012-06-08 21:42:437687 default:
7688 return false;
7689 }
7690}
7691
[email protected]a93bb842010-02-16 23:03:477692error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
7693 GLenum target,
7694 GLint level,
7695 GLenum internal_format,
7696 GLsizei width,
7697 GLsizei height,
7698 GLint border,
7699 GLsizei image_size,
7700 const void* data) {
[email protected]a93bb842010-02-16 23:03:477701 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:057702 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517703 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7704 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297705 return error::kNoError;
7706 }
[email protected]9438b012010-06-15 22:55:057707 if (!validators_->compressed_texture_format.IsValid(
7708 internal_format)) {
[email protected]ab09b612013-03-11 22:11:517709 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:537710 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:477711 return error::kNoError;
7712 }
[email protected]80eb6b52012-01-19 00:14:417713 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477714 border != 0) {
[email protected]ab09b612013-03-11 22:11:517715 LOCAL_SET_GL_ERROR(
7716 GL_INVALID_VALUE,
7717 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:477718 return error::kNoError;
7719 }
[email protected]c986af502013-08-14 01:04:447720 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7721 &state_, target);
[email protected]370eaf12013-05-18 09:19:497722 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517723 LOCAL_SET_GL_ERROR(
7724 GL_INVALID_VALUE,
7725 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:477726 return error::kNoError;
7727 }
[email protected]370eaf12013-05-18 09:19:497728 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:077729 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:517730 LOCAL_SET_GL_ERROR(
7731 GL_INVALID_OPERATION,
7732 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:437733 return error::kNoError;
7734 }
7735
7736 if (!ValidateCompressedTexDimensions(
7737 "glCompressedTexImage2D", level, width, height, internal_format) ||
7738 !ValidateCompressedTexFuncData(
7739 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:177740 return error::kNoError;
7741 }
[email protected]968351b2011-12-20 08:26:517742
[email protected]7989c9e2013-01-23 06:39:267743 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:517744 LOCAL_SET_GL_ERROR(
7745 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:267746 return error::kNoError;
7747 }
7748
[email protected]02965c22013-03-09 02:40:077749 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:447750 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:517751 }
7752
[email protected]40d90a22013-04-09 03:39:557753 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:477754 if (!data) {
7755 zero.reset(new int8[image_size]);
7756 memset(zero.get(), 0, image_size);
7757 data = zero.get();
7758 }
[email protected]ab09b612013-03-11 22:11:517759 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:477760 glCompressedTexImage2D(
7761 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:517762 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:437763 if (error == GL_NO_ERROR) {
7764 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:497765 texture_ref, target, level, internal_format,
7766 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:437767 }
[email protected]a93bb842010-02-16 23:03:477768 return error::kNoError;
7769}
7770
[email protected]f7a64ee2010-02-01 22:24:147771error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357772 uint32 immediate_data_size, const cmds::CompressedTexImage2D& c) {
[email protected]b9849abf2009-11-25 19:13:197773 GLenum target = static_cast<GLenum>(c.target);
7774 GLint level = static_cast<GLint>(c.level);
7775 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7776 GLsizei width = static_cast<GLsizei>(c.width);
7777 GLsizei height = static_cast<GLsizei>(c.height);
7778 GLint border = static_cast<GLint>(c.border);
7779 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
7780 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7781 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7782 const void* data = NULL;
7783 if (data_shm_id != 0 || data_shm_offset != 0) {
7784 data = GetSharedMemoryAs<const void*>(
7785 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:467786 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:147787 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197788 }
7789 }
[email protected]a93bb842010-02-16 23:03:477790 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:197791 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:197792}
7793
[email protected]b6140d02010-05-17 14:47:167794error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
[email protected]ed9f9cd2013-02-27 21:12:357795 uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167796 GLenum target = static_cast<GLenum>(c.target);
7797 GLint level = static_cast<GLint>(c.level);
7798 GLenum internal_format = static_cast<GLenum>(c.internalformat);
7799 GLsizei width = static_cast<GLsizei>(c.width);
7800 GLsizei height = static_cast<GLsizei>(c.height);
7801 GLint border = static_cast<GLint>(c.border);
7802 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287803 if (!bucket) {
7804 return error::kInvalidArguments;
7805 }
7806 uint32 data_size = bucket->size();
7807 GLsizei imageSize = data_size;
7808 const void* data = bucket->GetData(0, data_size);
7809 if (!data) {
7810 return error::kInvalidArguments;
7811 }
[email protected]b6140d02010-05-17 14:47:167812 return DoCompressedTexImage2D(
7813 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:287814 imageSize, data);
[email protected]b6140d02010-05-17 14:47:167815}
7816
7817error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
7818 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:357819 const cmds::CompressedTexSubImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:167820 GLenum target = static_cast<GLenum>(c.target);
7821 GLint level = static_cast<GLint>(c.level);
7822 GLint xoffset = static_cast<GLint>(c.xoffset);
7823 GLint yoffset = static_cast<GLint>(c.yoffset);
7824 GLsizei width = static_cast<GLsizei>(c.width);
7825 GLsizei height = static_cast<GLsizei>(c.height);
7826 GLenum format = static_cast<GLenum>(c.format);
7827 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:287828 if (!bucket) {
7829 return error::kInvalidArguments;
7830 }
[email protected]b6140d02010-05-17 14:47:167831 uint32 data_size = bucket->size();
7832 GLsizei imageSize = data_size;
7833 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:287834 if (!data) {
7835 return error::kInvalidArguments;
7836 }
[email protected]9438b012010-06-15 22:55:057837 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517838 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:537839 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:167840 return error::kNoError;
7841 }
[email protected]9438b012010-06-15 22:55:057842 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517843 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7844 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:057845 return error::kNoError;
7846 }
[email protected]b6140d02010-05-17 14:47:167847 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:517848 LOCAL_SET_GL_ERROR(
7849 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:167850 return error::kNoError;
7851 }
7852 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:517853 LOCAL_SET_GL_ERROR(
7854 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:167855 return error::kNoError;
7856 }
7857 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:517858 LOCAL_SET_GL_ERROR(
7859 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:167860 return error::kNoError;
7861 }
[email protected]cadde4a2010-07-31 17:10:437862 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:167863 target, level, xoffset, yoffset, width, height, format, imageSize, data);
7864 return error::kNoError;
7865}
7866
[email protected]f7a64ee2010-02-01 22:24:147867error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:357868 uint32 immediate_data_size, const cmds::TexImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:387869 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
[email protected]c986af502013-08-14 01:04:447870 // Set as failed for now, but if it successed, this will be set to not failed.
7871 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:197872 GLenum target = static_cast<GLenum>(c.target);
7873 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:447874 // TODO(kloveless): Change TexImage2D command to use unsigned integer
7875 // for internalformat.
7876 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:197877 GLsizei width = static_cast<GLsizei>(c.width);
7878 GLsizei height = static_cast<GLsizei>(c.height);
7879 GLint border = static_cast<GLint>(c.border);
7880 GLenum format = static_cast<GLenum>(c.format);
7881 GLenum type = static_cast<GLenum>(c.type);
7882 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
7883 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:187884 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347885 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247886 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:347887 NULL)) {
[email protected]a76b0052010-03-05 00:33:187888 return error::kOutOfBounds;
7889 }
[email protected]b9849abf2009-11-25 19:13:197890 const void* pixels = NULL;
7891 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
7892 pixels = GetSharedMemoryAs<const void*>(
7893 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:467894 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147895 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197896 }
7897 }
[email protected]f598f422012-12-07 08:30:037898
[email protected]c986af502013-08-14 01:04:447899 TextureManager::DoTextImage2DArguments args = {
7900 target, level, internal_format, width, height, border, format, type,
7901 pixels, pixels_size};
7902 texture_manager()->ValidateAndDoTexImage2D(
7903 &texture_state_, &state_, &framebuffer_state_, args);
[email protected]f598f422012-12-07 08:30:037904 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197905}
7906
[email protected]cadde4a2010-07-31 17:10:437907void GLES2DecoderImpl::DoCompressedTexSubImage2D(
7908 GLenum target,
7909 GLint level,
7910 GLint xoffset,
7911 GLint yoffset,
7912 GLsizei width,
7913 GLsizei height,
7914 GLenum format,
7915 GLsizei image_size,
7916 const void * data) {
[email protected]c986af502013-08-14 01:04:447917 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7918 &state_, target);
[email protected]370eaf12013-05-18 09:19:497919 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517920 LOCAL_SET_GL_ERROR(
7921 GL_INVALID_OPERATION,
7922 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437923 return;
7924 }
[email protected]370eaf12013-05-18 09:19:497925 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:437926 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:527927 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:077928 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:517929 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:527930 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437931 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:527932 return;
7933 }
7934 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:517935 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:527936 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:437937 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:527938 return;
7939 }
[email protected]02965c22013-03-09 02:40:077940 if (!texture->ValidForTexture(
[email protected]df6cf1ad2011-01-29 01:20:527941 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:517942 LOCAL_SET_GL_ERROR(
7943 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:437944 return;
7945 }
[email protected]ad84a3a2012-06-08 21:42:437946
7947 if (!ValidateCompressedTexFuncData(
7948 "glCompressedTexSubImage2D", width, height, format, image_size) ||
7949 !ValidateCompressedTexSubDimensions(
7950 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:077951 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:437952 return;
7953 }
7954
7955
[email protected]0d6bfdc2011-11-02 01:32:207956 // Note: There is no need to deal with texture cleared tracking here
7957 // because the validation above means you can only get here if the level
7958 // is already a matching compressed format and in that case
7959 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:437960 glCompressedTexSubImage2D(
7961 target, level, xoffset, yoffset, width, height, format, image_size, data);
7962}
7963
[email protected]6e288612010-12-21 20:45:037964static void Clip(
7965 GLint start, GLint range, GLint sourceRange,
7966 GLint* out_start, GLint* out_range) {
7967 DCHECK(out_start);
7968 DCHECK(out_range);
7969 if (start < 0) {
7970 range += start;
7971 start = 0;
7972 }
7973 GLint end = start + range;
7974 if (end > sourceRange) {
7975 range -= end - sourceRange;
7976 }
7977 *out_start = start;
7978 *out_range = range;
7979}
7980
[email protected]cadde4a2010-07-31 17:10:437981void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:447982 GLenum target,
7983 GLint level,
7984 GLenum internal_format,
7985 GLint x,
7986 GLint y,
7987 GLsizei width,
7988 GLsizei height,
7989 GLint border) {
[email protected]09e17272012-11-30 10:30:447990 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:447991 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7992 &state_, target);
[email protected]370eaf12013-05-18 09:19:497993 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517994 LOCAL_SET_GL_ERROR(
7995 GL_INVALID_OPERATION,
7996 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:437997 return;
7998 }
[email protected]370eaf12013-05-18 09:19:497999 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078000 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518001 LOCAL_SET_GL_ERROR(
8002 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:178003 }
[email protected]80eb6b52012-01-19 00:14:418004 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:188005 border != 0) {
[email protected]ab09b612013-03-11 22:11:518006 LOCAL_SET_GL_ERROR(
8007 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188008 return;
8009 }
[email protected]c986af502013-08-14 01:04:448010 if (!texture_manager()->ValidateTextureParameters(
8011 state_.GetErrorState(), "glCopyTexImage2D", target, internal_format,
8012 GL_UNSIGNED_BYTE, level)) {
[email protected]81375742012-06-08 00:04:008013 return;
8014 }
[email protected]f5719fb2010-08-04 18:27:188015
[email protected]9edc6b22010-12-23 02:00:268016 // Check we have compatible formats.
8017 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8018 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8019 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8020
8021 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518022 LOCAL_SET_GL_ERROR(
8023 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268024 return;
8025 }
8026
[email protected]81375742012-06-08 00:04:008027 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518028 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008029 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268030 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8031 return;
8032 }
8033
8034 uint32 estimated_size = 0;
8035 if (!GLES2Util::ComputeImageDataSizes(
8036 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8037 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518038 LOCAL_SET_GL_ERROR(
8039 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268040 return;
8041 }
8042
8043 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518044 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008045 return;
8046 }
8047
[email protected]a0b78dc2011-11-11 10:43:108048 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8049 return;
8050 }
8051
[email protected]ab09b612013-03-11 22:11:518052 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278053 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038054 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268055
[email protected]02965c22013-03-09 02:40:078056 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448057 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:468058 }
8059
[email protected]9edc6b22010-12-23 02:00:268060 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038061 GLint copyX = 0;
8062 GLint copyY = 0;
8063 GLint copyWidth = 0;
8064 GLint copyHeight = 0;
8065 Clip(x, width, size.width(), &copyX, &copyWidth);
8066 Clip(y, height, size.height(), &copyY, &copyHeight);
8067
8068 if (copyX != x ||
8069 copyY != y ||
8070 copyWidth != width ||
8071 copyHeight != height) {
8072 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208073 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078074 texture->service_id(), texture->target(),
[email protected]4502e6492011-12-14 19:39:158075 target, level, internal_format, GL_UNSIGNED_BYTE, width, height,
[email protected]02965c22013-03-09 02:40:078076 texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518077 LOCAL_SET_GL_ERROR(
8078 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038079 return;
8080 }
[email protected]6e288612010-12-21 20:45:038081 if (copyHeight > 0 && copyWidth > 0) {
8082 GLint dx = copyX - x;
8083 GLint dy = copyY - y;
8084 GLint destX = dx;
8085 GLint destY = dy;
8086 glCopyTexSubImage2D(target, level,
8087 destX, destY, copyX, copyY,
8088 copyWidth, copyHeight);
8089 }
8090 } else {
8091 glCopyTexImage2D(target, level, internal_format,
8092 copyX, copyY, copyWidth, copyHeight, border);
8093 }
[email protected]ab09b612013-03-11 22:11:518094 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438095 if (error == GL_NO_ERROR) {
8096 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498097 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208098 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438099 }
8100}
8101
8102void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448103 GLenum target,
8104 GLint level,
8105 GLint xoffset,
8106 GLint yoffset,
8107 GLint x,
8108 GLint y,
8109 GLsizei width,
8110 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448111 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448112 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8113 &state_, target);
[email protected]370eaf12013-05-18 09:19:498114 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518115 LOCAL_SET_GL_ERROR(
8116 GL_INVALID_OPERATION,
8117 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438118 return;
8119 }
[email protected]370eaf12013-05-18 09:19:498120 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438121 GLenum type = 0;
8122 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078123 if (!texture->GetLevelType(target, level, &type, &format) ||
8124 !texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438125 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518126 LOCAL_SET_GL_ERROR(
8127 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438128 return;
8129 }
[email protected]85a4ac22013-05-31 01:58:478130 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518131 LOCAL_SET_GL_ERROR(
8132 GL_INVALID_OPERATION,
8133 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598134 return;
8135 }
[email protected]9edc6b22010-12-23 02:00:268136
8137 // Check we have compatible formats.
8138 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8139 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8140 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8141
[email protected]2d3765b2012-10-03 00:31:078142 if (!channels_needed ||
8143 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518144 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438145 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268146 return;
8147 }
8148
[email protected]81375742012-06-08 00:04:008149 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518150 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008151 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438152 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008153 return;
8154 }
8155
[email protected]a0b78dc2011-11-11 10:43:108156 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8157 return;
8158 }
8159
[email protected]de26b3c2011-08-03 21:54:278160 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038161 gfx::Size size = GetBoundReadFrameBufferSize();
8162 GLint copyX = 0;
8163 GLint copyY = 0;
8164 GLint copyWidth = 0;
8165 GLint copyHeight = 0;
8166 Clip(x, width, size.width(), &copyX, &copyWidth);
8167 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208168
[email protected]370eaf12013-05-18 09:19:498169 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:518170 LOCAL_SET_GL_ERROR(
8171 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208172 return;
8173 }
8174
[email protected]6e288612010-12-21 20:45:038175 if (copyX != x ||
8176 copyY != y ||
8177 copyWidth != width ||
8178 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208179 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038180 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348181 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248182 width, height, format, type, state_.unpack_alignment, &pixels_size,
8183 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518184 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438185 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038186 return;
8187 }
[email protected]40d90a22013-04-09 03:39:558188 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038189 memset(zero.get(), 0, pixels_size);
8190 glTexSubImage2D(
8191 target, level, xoffset, yoffset, width, height,
8192 format, type, zero.get());
8193 }
[email protected]0d6bfdc2011-11-02 01:32:208194
[email protected]6e288612010-12-21 20:45:038195 if (copyHeight > 0 && copyWidth > 0) {
8196 GLint dx = copyX - x;
8197 GLint dy = copyY - y;
8198 GLint destX = xoffset + dx;
8199 GLint destY = yoffset + dy;
8200 glCopyTexSubImage2D(target, level,
8201 destX, destY, copyX, copyY,
8202 copyWidth, copyHeight);
8203 }
[email protected]cadde4a2010-07-31 17:10:438204}
8205
[email protected]f598f422012-12-07 08:30:038206bool GLES2DecoderImpl::ValidateTexSubImage2D(
8207 error::Error* error,
8208 const char* function_name,
8209 GLenum target,
8210 GLint level,
8211 GLint xoffset,
8212 GLint yoffset,
8213 GLsizei width,
8214 GLsizei height,
8215 GLenum format,
8216 GLenum type,
8217 const void * data) {
8218 (*error) = error::kNoError;
8219 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518220 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038221 return false;
8222 }
8223 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518224 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038225 return false;
8226 }
8227 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518228 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038229 return false;
8230 }
8231 if (!validators_->texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518232 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]f598f422012-12-07 08:30:038233 return false;
8234 }
8235 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:518236 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]f598f422012-12-07 08:30:038237 return false;
8238 }
[email protected]c986af502013-08-14 01:04:448239 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8240 &state_, target);
[email protected]370eaf12013-05-18 09:19:498241 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518242 LOCAL_SET_GL_ERROR(
8243 GL_INVALID_OPERATION,
8244 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038245 return false;
[email protected]cadde4a2010-07-31 17:10:438246 }
[email protected]370eaf12013-05-18 09:19:498247 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:528248 GLenum current_type = 0;
8249 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078250 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518251 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038252 GL_INVALID_OPERATION, function_name, "level does not exist.");
8253 return false;
[email protected]df6cf1ad2011-01-29 01:20:528254 }
8255 if (format != internal_format) {
[email protected]ab09b612013-03-11 22:11:518256 LOCAL_SET_GL_ERROR(
8257 GL_INVALID_OPERATION,
8258 function_name, "format does not match internal format.");
[email protected]f598f422012-12-07 08:30:038259 return false;
[email protected]df6cf1ad2011-01-29 01:20:528260 }
8261 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518262 LOCAL_SET_GL_ERROR(
8263 GL_INVALID_OPERATION,
8264 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038265 return false;
[email protected]df6cf1ad2011-01-29 01:20:528266 }
[email protected]85a4ac22013-05-31 01:58:478267 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518268 LOCAL_SET_GL_ERROR(
8269 GL_INVALID_OPERATION,
8270 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598271 return false;
8272 }
[email protected]02965c22013-03-09 02:40:078273 if (!texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438274 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518275 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038276 return false;
[email protected]cadde4a2010-07-31 17:10:438277 }
[email protected]81375742012-06-08 00:04:008278 if ((GLES2Util::GetChannelsForFormat(format) &
8279 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518280 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008281 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038282 function_name, "can not supply data for depth or stencil textures");
8283 return false;
[email protected]81375742012-06-08 00:04:008284 }
[email protected]f598f422012-12-07 08:30:038285 if (data == NULL) {
8286 (*error) = error::kOutOfBounds;
8287 return false;
8288 }
8289 return true;
8290}
[email protected]81375742012-06-08 00:04:008291
[email protected]f598f422012-12-07 08:30:038292error::Error GLES2DecoderImpl::DoTexSubImage2D(
8293 GLenum target,
8294 GLint level,
8295 GLint xoffset,
8296 GLint yoffset,
8297 GLsizei width,
8298 GLsizei height,
8299 GLenum format,
8300 GLenum type,
8301 const void * data) {
8302 error::Error error = error::kNoError;
8303 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8304 xoffset, yoffset, width, height, format, type, data)) {
8305 return error;
8306 }
[email protected]c986af502013-08-14 01:04:448307 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8308 &state_, target);
[email protected]370eaf12013-05-18 09:19:498309 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:158310 GLsizei tex_width = 0;
8311 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078312 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:158313 DCHECK(ok);
8314 if (xoffset != 0 || yoffset != 0 ||
8315 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:498316 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
8317 target, level)) {
[email protected]ab09b612013-03-11 22:11:518318 LOCAL_SET_GL_ERROR(
8319 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038320 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308321 }
[email protected]c986af502013-08-14 01:04:448322 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158323 glTexSubImage2D(
8324 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038325 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208326 }
[email protected]4502e6492011-12-14 19:39:158327
[email protected]c986af502013-08-14 01:04:448328 if (texture_state_.teximage2d_faster_than_texsubimage2d &&
8329 !texture->IsImmutable()) {
8330 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158331 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
8332 // same as internal_foramt. If that changes we'll need to look them up.
[email protected]8f1d2aa2013-05-10 23:45:388333 glTexImage2D(
[email protected]4502e6492011-12-14 19:39:158334 target, level, format, width, height, 0, format, type, data);
8335 } else {
[email protected]c986af502013-08-14 01:04:448336 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158337 glTexSubImage2D(
8338 target, level, xoffset, yoffset, width, height, format, type, data);
8339 }
[email protected]370eaf12013-05-18 09:19:498340 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]f598f422012-12-07 08:30:038341 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438342}
8343
[email protected]b493ee622011-04-13 23:52:008344error::Error GLES2DecoderImpl::HandleTexSubImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358345 uint32 immediate_data_size, const cmds::TexSubImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388346 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
[email protected]b493ee622011-04-13 23:52:008347 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:448348 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:008349 return error::kNoError;
8350
8351 GLenum target = static_cast<GLenum>(c.target);
8352 GLint level = static_cast<GLint>(c.level);
8353 GLint xoffset = static_cast<GLint>(c.xoffset);
8354 GLint yoffset = static_cast<GLint>(c.yoffset);
8355 GLsizei width = static_cast<GLsizei>(c.width);
8356 GLsizei height = static_cast<GLsizei>(c.height);
8357 GLenum format = static_cast<GLenum>(c.format);
8358 GLenum type = static_cast<GLenum>(c.type);
8359 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348360 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248361 width, height, format, type, state_.unpack_alignment, &data_size,
8362 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008363 return error::kOutOfBounds;
8364 }
8365 const void* pixels = GetSharedMemoryAs<const void*>(
8366 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038367 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008368 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008369}
8370
[email protected]f7a64ee2010-02-01 22:24:148371error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]ed9f9cd2013-02-27 21:12:358372 uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:368373 GLuint index = static_cast<GLuint>(c.index);
8374 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:358375 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:258376 Result* result = GetSharedMemoryAs<Result*>(
8377 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:368378 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:148379 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:368380 }
[email protected]07d0cc82010-02-17 04:51:408381 // Check that the client initialized the result.
8382 if (result->size != 0) {
8383 return error::kInvalidArguments;
8384 }
[email protected]9438b012010-06-15 22:55:058385 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:518386 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8387 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:148388 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368389 }
[email protected]3916c97e2010-02-25 03:20:508390 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:518391 LOCAL_SET_GL_ERROR(
8392 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:148393 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368394 }
[email protected]0bfd9882010-02-05 23:02:258395 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:088396 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:358397 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:148398 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328399}
8400
[email protected]f7b85372010-02-03 01:11:378401bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:428402 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:378403 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:128404 error::Error* error, GLint* real_location,
8405 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:108406 DCHECK(error);
8407 DCHECK(service_id);
8408 DCHECK(result_pointer);
8409 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:128410 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:378411 *error = error::kNoError;
8412 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:258413 SizedResult<GLint>* result;
8414 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8415 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8416 if (!result) {
[email protected]f7b85372010-02-03 01:11:378417 *error = error::kOutOfBounds;
8418 return false;
8419 }
[email protected]0bfd9882010-02-05 23:02:258420 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:378421 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:258422 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:428423 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
8424 if (!program) {
[email protected]ae51d192010-04-27 00:48:038425 return false;
8426 }
[email protected]df37b9932013-03-08 05:21:428427 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:378428 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:518429 LOCAL_SET_GL_ERROR(
8430 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:378431 return false;
8432 }
[email protected]df37b9932013-03-08 05:21:428433 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:368434 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:358435 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428436 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:128437 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:368438 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:378439 // No such location.
[email protected]ab09b612013-03-11 22:11:518440 LOCAL_SET_GL_ERROR(
8441 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:378442 return false;
8443 }
[email protected]43c2f1f2011-03-25 18:35:368444 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:508445 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:378446 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:518447 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:378448 return false;
8449 }
[email protected]0bfd9882010-02-05 23:02:258450 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8451 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8452 if (!result) {
[email protected]f7b85372010-02-03 01:11:378453 *error = error::kOutOfBounds;
8454 return false;
8455 }
[email protected]0bfd9882010-02-05 23:02:258456 result->size = size;
[email protected]939e7362010-05-13 20:49:108457 *result_type = type;
[email protected]f7b85372010-02-03 01:11:378458 return true;
8459}
8460
[email protected]f7a64ee2010-02-01 22:24:148461error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]ed9f9cd2013-02-27 21:12:358462 uint32 immediate_data_size, const cmds::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:378463 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338464 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378465 GLuint service_id;
[email protected]939e7362010-05-13 20:49:108466 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:128467 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378468 Error error;
[email protected]0bfd9882010-02-05 23:02:258469 void* result;
[email protected]f7b85372010-02-03 01:11:378470 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128471 program, fake_location, c.params_shm_id, c.params_shm_offset,
8472 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:258473 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:128474 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:358475 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:378476 }
8477 return error;
[email protected]96449d2c2009-11-25 00:01:328478}
8479
[email protected]f7a64ee2010-02-01 22:24:148480error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]ed9f9cd2013-02-27 21:12:358481 uint32 immediate_data_size, const cmds::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:378482 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338483 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378484 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:128485 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378486 Error error;
[email protected]ed9f9cd2013-02-27 21:12:358487 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:108488 Result* result;
8489 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:378490 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128491 program, fake_location, c.params_shm_id, c.params_shm_offset,
8492 &error, &real_location, &service_id,
8493 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:108494 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8495 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8496 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:558497 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:128498 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:108499 GLfloat* dst = result->GetData();
8500 for (GLsizei ii = 0; ii < num_values; ++ii) {
8501 dst[ii] = (temp[ii] != 0);
8502 }
8503 } else {
[email protected]1b0a6752012-02-22 03:44:128504 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:108505 }
[email protected]f7b85372010-02-03 01:11:378506 }
8507 return error;
[email protected]96449d2c2009-11-25 00:01:328508}
8509
[email protected]f7a64ee2010-02-01 22:24:148510error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]ed9f9cd2013-02-27 21:12:358511 uint32 immediate_data_size, const cmds::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:258512 GLenum shader_type = static_cast<GLenum>(c.shadertype);
8513 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:358514 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:258515 Result* result = GetSharedMemoryAs<Result*>(
8516 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8517 if (!result) {
8518 return error::kOutOfBounds;
8519 }
[email protected]07d0cc82010-02-17 04:51:408520 // Check that the client initialized the result.
8521 if (result->success != 0) {
8522 return error::kInvalidArguments;
8523 }
[email protected]9438b012010-06-15 22:55:058524 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:518525 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538526 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:298527 return error::kNoError;
8528 }
[email protected]9438b012010-06-15 22:55:058529 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:518530 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538531 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:298532 return error::kNoError;
8533 }
8534
8535 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:408536
[email protected]46c86752013-05-21 05:08:398537 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:408538 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:218539 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:408540
8541 result->min_range = range[0];
8542 result->max_range = range[1];
8543 result->precision = precision;
8544
[email protected]f7a64ee2010-02-01 22:24:148545 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328546}
8547
[email protected]f7a64ee2010-02-01 22:24:148548error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]ed9f9cd2013-02-27 21:12:358549 uint32 immediate_data_size, const cmds::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:258550 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:428551 GLuint program_id = static_cast<GLuint>(c.program);
8552 Program* program = GetProgramInfoNotShader(
8553 program_id, "glGetAttachedShaders");
8554 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258555 return error::kNoError;
8556 }
[email protected]ed9f9cd2013-02-27 21:12:358557 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:258558 uint32 max_count = Result::ComputeMaxResults(result_size);
8559 Result* result = GetSharedMemoryAs<Result*>(
8560 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8561 if (!result) {
8562 return error::kOutOfBounds;
8563 }
[email protected]07d0cc82010-02-17 04:51:408564 // Check that the client initialized the result.
8565 if (result->size != 0) {
8566 return error::kInvalidArguments;
8567 }
[email protected]0bfd9882010-02-05 23:02:258568 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:038569 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:428570 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:258571 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:038572 if (!shader_manager()->GetClientId(result->GetData()[ii],
8573 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:258574 NOTREACHED();
8575 return error::kGenericError;
8576 }
8577 }
8578 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:148579 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328580}
8581
[email protected]f7a64ee2010-02-01 22:24:148582error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]ed9f9cd2013-02-27 21:12:358583 uint32 immediate_data_size, const cmds::GetActiveUniform& c) {
[email protected]df37b9932013-03-08 05:21:428584 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258585 GLuint index = c.index;
8586 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358587 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:258588 Result* result = GetSharedMemoryAs<Result*>(
8589 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8590 if (!result) {
8591 return error::kOutOfBounds;
8592 }
[email protected]07d0cc82010-02-17 04:51:408593 // Check that the client initialized the result.
8594 if (result->success != 0) {
8595 return error::kInvalidArguments;
8596 }
[email protected]df37b9932013-03-08 05:21:428597 Program* program = GetProgramInfoNotShader(
8598 program_id, "glGetActiveUniform");
8599 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258600 return error::kNoError;
8601 }
[email protected]ed9f9cd2013-02-27 21:12:358602 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428603 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:258604 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:518605 LOCAL_SET_GL_ERROR(
8606 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258607 return error::kNoError;
8608 }
8609 result->success = 1; // true.
8610 result->size = uniform_info->size;
8611 result->type = uniform_info->type;
8612 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298613 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148614 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328615}
8616
[email protected]f7a64ee2010-02-01 22:24:148617error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]ed9f9cd2013-02-27 21:12:358618 uint32 immediate_data_size, const cmds::GetActiveAttrib& c) {
[email protected]df37b9932013-03-08 05:21:428619 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258620 GLuint index = c.index;
8621 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358622 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:258623 Result* result = GetSharedMemoryAs<Result*>(
8624 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8625 if (!result) {
8626 return error::kOutOfBounds;
8627 }
[email protected]07d0cc82010-02-17 04:51:408628 // Check that the client initialized the result.
8629 if (result->success != 0) {
8630 return error::kInvalidArguments;
8631 }
[email protected]df37b9932013-03-08 05:21:428632 Program* program = GetProgramInfoNotShader(
8633 program_id, "glGetActiveAttrib");
8634 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258635 return error::kNoError;
8636 }
[email protected]ed9f9cd2013-02-27 21:12:358637 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:428638 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:258639 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:518640 LOCAL_SET_GL_ERROR(
8641 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258642 return error::kNoError;
8643 }
8644 result->success = 1; // true.
8645 result->size = attrib_info->size;
8646 result->type = attrib_info->type;
8647 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298648 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148649 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328650}
8651
[email protected]b273e432010-04-12 17:23:588652error::Error GLES2DecoderImpl::HandleShaderBinary(
[email protected]ed9f9cd2013-02-27 21:12:358653 uint32 immediate_data_size, const cmds::ShaderBinary& c) {
[email protected]b273e432010-04-12 17:23:588654#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:518655 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:588656 return error::kNoError;
8657#else
8658 GLsizei n = static_cast<GLsizei>(c.n);
8659 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:518660 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:588661 return error::kNoError;
8662 }
8663 GLsizei length = static_cast<GLsizei>(c.length);
8664 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:518665 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:588666 return error::kNoError;
8667 }
8668 uint32 data_size;
8669 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
8670 return error::kOutOfBounds;
8671 }
8672 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
8673 c.shaders_shm_id, c.shaders_shm_offset, data_size);
8674 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
8675 const void* binary = GetSharedMemoryAs<const void*>(
8676 c.binary_shm_id, c.binary_shm_offset, length);
8677 if (shaders == NULL || binary == NULL) {
8678 return error::kOutOfBounds;
8679 }
8680 scoped_array<GLuint> service_ids(new GLuint[n]);
8681 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:428682 Shader* shader = GetShader(shaders[ii]);
8683 if (!shader) {
[email protected]ab09b612013-03-11 22:11:518684 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:588685 return error::kNoError;
8686 }
[email protected]df37b9932013-03-08 05:21:428687 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:588688 }
8689 // TODO(gman): call glShaderBinary
8690 return error::kNoError;
8691#endif
8692}
8693
[email protected]6d792ee12013-05-15 00:40:568694void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:498695 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:088696
[email protected]64ace852011-05-19 21:49:498697 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:428698 // TRACE_EVENT for gpu tests:
8699 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:428700 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:428701 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
8702 "width", (is_offscreen ? offscreen_size_.width() :
8703 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:568704 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:498705 "offscreen", is_offscreen,
8706 "frame", this_frame_number);
[email protected]8f9b8dd2013-09-12 18:05:138707 bool is_tracing;
8708 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
8709 &is_tracing);
8710 if (is_tracing) {
8711 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
8712 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
8713 is_offscreen ? offscreen_size_ : surface_->GetSize());
8714 }
8715
[email protected]6217d392010-03-25 22:08:358716 // If offscreen then don't actually SwapBuffers to the display. Just copy
8717 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:498718 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:318719 TRACE_EVENT2("gpu", "Offscreen",
8720 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:538721 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
8722 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
8723 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
8724 // fix this.
[email protected]62e155e2012-10-23 22:43:158725 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:538726 offscreen_saved_frame_buffer_->Create();
8727 glFinish();
8728 }
8729
8730 // Allocate the offscreen saved color texture.
8731 DCHECK(offscreen_saved_color_format_);
8732 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:098733 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:538734
8735 offscreen_saved_frame_buffer_->AttachRenderTexture(
8736 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:058737 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
8738 if (offscreen_saved_frame_buffer_->CheckStatus() !=
8739 GL_FRAMEBUFFER_COMPLETE) {
8740 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
8741 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:568742 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
8743 return;
[email protected]f0cfe752013-01-14 01:09:058744 }
[email protected]1fb8c482011-08-31 01:01:538745
[email protected]f0cfe752013-01-14 01:09:058746 // Clear the offscreen color texture.
8747 // TODO(piman): Is this still necessary?
8748 {
8749 ScopedFrameBufferBinder binder(this,
8750 offscreen_saved_frame_buffer_->id());
8751 glClearColor(0, 0, 0, 0);
8752 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
8753 glDisable(GL_SCISSOR_TEST);
8754 glClear(GL_COLOR_BUFFER_BIT);
8755 RestoreClearState();
8756 }
[email protected]1fb8c482011-08-31 01:01:538757 }
8758
8759 UpdateParentTextureInfo();
8760 }
8761
[email protected]f0cfe752013-01-14 01:09:058762 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:568763 return;
[email protected]ab09b612013-03-11 22:11:518764 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:308765 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:358766
[email protected]34ff8b0c2010-10-01 20:06:028767 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:138768 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:278769 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:488770 } else {
[email protected]069944672012-04-25 20:52:238771 ScopedFrameBufferBinder binder(this,
8772 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:138773
[email protected]069944672012-04-25 20:52:238774 if (offscreen_target_buffer_preserved_) {
8775 // Copy the target frame buffer to the saved offscreen texture.
8776 offscreen_saved_color_texture_->Copy(
8777 offscreen_saved_color_texture_->size(),
8778 offscreen_saved_color_format_);
8779 } else {
8780 // Flip the textures in the parent context via the texture manager.
8781 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:498782 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:238783 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:568784
[email protected]069944672012-04-25 20:52:238785 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
8786 offscreen_target_frame_buffer_->AttachRenderTexture(
8787 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:488788 }
[email protected]069944672012-04-25 20:52:238789
8790 // Ensure the side effects of the copy are visible to the parent
8791 // context. There is no need to do this for ANGLE because it uses a
8792 // single D3D device for all contexts.
8793 if (!IsAngle())
8794 glFlush();
[email protected]0c8c9d22010-06-25 17:36:398795 }
[email protected]6217d392010-03-25 22:08:358796 } else {
[email protected]111975c62012-09-06 01:37:318797 TRACE_EVENT2("gpu", "Onscreen",
8798 "width", surface_->GetSize().width(),
8799 "height", surface_->GetSize().height());
[email protected]f62a5ab2011-05-23 20:34:158800 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:018801 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:568802 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:018803 }
[email protected]6217d392010-03-25 22:08:358804 }
[email protected]6217d392010-03-25 22:08:358805}
8806
[email protected]d4239852011-08-12 04:51:228807error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358808 uint32 immediate_data_size, const cmds::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:188809 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288810 if (!bucket || bucket->size() == 0) {
8811 return error::kInvalidArguments;
8812 }
[email protected]ed9f9cd2013-02-27 21:12:358813 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:188814 Result* result = GetSharedMemoryAs<Result*>(
8815 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8816 if (!result) {
8817 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:108818 }
[email protected]b1d2dcb2010-05-17 19:24:188819 // Check that the client initialized the result.
8820 if (*result != 0) {
8821 return error::kInvalidArguments;
8822 }
8823 std::string feature_str;
8824 if (!bucket->GetAsString(&feature_str)) {
8825 return error::kInvalidArguments;
8826 }
8827
8828 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:228829 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:188830 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:228831 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:408832 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
8833 // TODO(gman): decide how to remove the need for this const_cast.
8834 // I could make validators_ non const but that seems bad as this is the only
8835 // place it is needed. I could make some special friend class of validators
8836 // just to allow this to set them. That seems silly. I could refactor this
8837 // code to use the extension mechanism or the initialization attributes to
8838 // turn this feature on. Given that the only real point of this is to make
8839 // the conformance tests pass and given that there is lots of real work that
8840 // needs to be done it seems like refactoring for one to one of those
8841 // methods is a very low priority.
8842 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:048843 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
8844 force_webgl_glsl_validation_ = true;
8845 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:188846 } else {
8847 return error::kNoError;
8848 }
8849
8850 *result = 1; // true.
8851 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:108852}
8853
[email protected]c2f8c8402010-12-06 18:07:248854error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
8855 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:358856 const cmds::GetRequestableExtensionsCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:248857 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:358858 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:198859 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:248860 bucket->SetFromString(info->extensions().c_str());
8861 return error::kNoError;
8862}
8863
8864error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358865 uint32 immediate_data_size, const cmds::RequestExtensionCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:248866 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288867 if (!bucket || bucket->size() == 0) {
8868 return error::kInvalidArguments;
8869 }
[email protected]c2f8c8402010-12-06 18:07:248870 std::string feature_str;
8871 if (!bucket->GetAsString(&feature_str)) {
8872 return error::kInvalidArguments;
8873 }
8874
[email protected]4b7eba92013-01-08 02:23:568875 bool desire_webgl_glsl_validation =
8876 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
8877 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:498878 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:138879 bool desire_draw_buffers = false;
[email protected]4b7eba92013-01-08 02:23:568880 if (force_webgl_glsl_validation_) {
8881 desire_standard_derivatives =
8882 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:498883 desire_frag_depth =
8884 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:138885 desire_draw_buffers =
8886 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:048887 }
8888
[email protected]4b7eba92013-01-08 02:23:568889 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:498890 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:138891 desire_frag_depth != frag_depth_explicitly_enabled_ ||
8892 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:498893 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
8894 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
8895 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:138896 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]c2f8c8402010-12-06 18:07:248897 InitializeShaderTranslator();
8898 }
8899
[email protected]302ce6d2011-07-07 23:28:118900 UpdateCapabilities();
8901
[email protected]c2f8c8402010-12-06 18:07:248902 return error::kNoError;
8903}
8904
[email protected]372e0412011-06-28 16:08:568905error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358906 uint32 immediate_data_size, const cmds::GetMultipleIntegervCHROMIUM& c) {
[email protected]372e0412011-06-28 16:08:568907 GLuint count = c.count;
8908 uint32 pnames_size;
8909 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
8910 return error::kOutOfBounds;
8911 }
8912 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
8913 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
8914 if (pnames == NULL) {
8915 return error::kOutOfBounds;
8916 }
8917
8918 // We have to copy them since we use them twice so the client
8919 // can't change them between the time we validate them and the time we use
8920 // them.
[email protected]40d90a22013-04-09 03:39:558921 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:568922 memcpy(enums.get(), pnames, pnames_size);
8923
8924 // Count up the space needed for the result.
8925 uint32 num_results = 0;
8926 for (GLuint ii = 0; ii < count; ++ii) {
8927 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
8928 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:518929 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8930 "glGetMulitpleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:568931 return error::kNoError;
8932 }
8933 // Num will never be more than 4.
8934 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:478935 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:568936 return error::kOutOfBounds;
8937 }
8938 }
8939
8940 uint32 result_size = 0;
8941 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
8942 return error::kOutOfBounds;
8943 }
8944
8945 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:518946 LOCAL_SET_GL_ERROR(
8947 GL_INVALID_VALUE,
8948 "glGetMulitpleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:568949 return error::kNoError;
8950 }
8951
8952 GLint* results = GetSharedMemoryAs<GLint*>(
8953 c.results_shm_id, c.results_shm_offset, result_size);
8954 if (results == NULL) {
8955 return error::kOutOfBounds;
8956 }
8957
8958 // Check the results have been cleared in case the context was lost.
8959 for (uint32 ii = 0; ii < num_results; ++ii) {
8960 if (results[ii]) {
8961 return error::kInvalidArguments;
8962 }
8963 }
8964
8965 // Get each result.
8966 GLint* start = results;
8967 for (GLuint ii = 0; ii < count; ++ii) {
8968 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:268969 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:538970 !GetHelper(enums[ii], results, &num_written)) {
[email protected]b0ce0982013-05-13 18:51:488971 DoGetIntegerv(enums[ii], results);
[email protected]372e0412011-06-28 16:08:568972 }
8973 results += num_written;
8974 }
8975
8976 // Just to verify. Should this be a DCHECK?
8977 if (static_cast<uint32>(results - start) != num_results) {
8978 return error::kOutOfBounds;
8979 }
8980
8981 return error::kNoError;
8982}
8983
[email protected]2318d342011-07-11 22:27:428984error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:358985 uint32 immediate_data_size, const cmds::GetProgramInfoCHROMIUM& c) {
[email protected]df37b9932013-03-08 05:21:428986 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:428987 uint32 bucket_id = c.bucket_id;
8988 Bucket* bucket = CreateBucket(bucket_id);
8989 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:428990 Program* program = NULL;
8991 program = GetProgram(program_id);
8992 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:468993 return error::kNoError;
[email protected]2318d342011-07-11 22:27:428994 }
[email protected]df37b9932013-03-08 05:21:428995 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:428996 return error::kNoError;
8997}
8998
[email protected]38d139d2011-07-14 00:38:438999error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9000 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:439001 case GL_NO_ERROR:
9002 // TODO(kbr): improve the precision of the error code in this case.
9003 // Consider delegating to context for error code if MakeCurrent fails.
9004 return error::kUnknown;
9005 case GL_GUILTY_CONTEXT_RESET_ARB:
9006 return error::kGuilty;
9007 case GL_INNOCENT_CONTEXT_RESET_ARB:
9008 return error::kInnocent;
9009 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9010 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439011 }
9012
9013 NOTREACHED();
9014 return error::kUnknown;
9015}
9016
9017bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099018 if (reset_status_ != GL_NO_ERROR) {
9019 return true;
9020 }
[email protected]706b69f2012-07-27 04:59:309021 if (context_->WasAllocatedUsingRobustnessExtension()) {
9022 GLenum status = GL_NO_ERROR;
9023 if (has_robustness_extension_)
9024 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439025 if (status != GL_NO_ERROR) {
9026 // The graphics card was reset. Signal a lost context to the application.
9027 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:229028 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:439029 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099030 << " context lost via ARB/EXT_robustness. Reset status = "
9031 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:439032 return true;
9033 }
9034 }
9035 return false;
9036}
9037
[email protected]93a7d98f2013-07-11 00:04:229038bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
9039 return WasContextLost() && reset_by_robustness_extension_;
9040}
9041
[email protected]c4485aad62012-12-17 10:19:099042void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9043 // Only loses the context once.
9044 if (reset_status_ != GL_NO_ERROR) {
9045 return;
9046 }
9047
9048 // Marks this context as lost.
9049 reset_status_ = reset_status;
9050 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:099051}
9052
9053error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359054 uint32 immediate_data_size, const cmds::LoseContextCHROMIUM& c) {
[email protected]c4485aad62012-12-17 10:19:099055 GLenum current = static_cast<GLenum>(c.current);
9056 GLenum other = static_cast<GLenum>(c.other);
9057 if (!validators_->reset_status.IsValid(current)) {
[email protected]ab09b612013-03-11 22:11:519058 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9059 "glLoseContextCHROMIUM", current, "current");
[email protected]c4485aad62012-12-17 10:19:099060 }
9061 if (!validators_->reset_status.IsValid(other)) {
[email protected]ab09b612013-03-11 22:11:519062 LOCAL_SET_GL_ERROR_INVALID_ENUM("glLoseContextCHROMIUM", other, "other");
[email protected]c4485aad62012-12-17 10:19:099063 }
9064 group_->LoseContexts(other);
9065 reset_status_ = current;
9066 current_decoder_error_ = error::kLostContext;
9067 return error::kLostContext;
9068}
9069
[email protected]b096d032013-03-08 03:08:019070error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
9071 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) {
9072 return error::kUnknownCommand;
9073}
9074
[email protected]840a7e462013-02-27 01:29:519075error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359076 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) {
[email protected]840a7e462013-02-27 01:29:519077 if (wait_sync_point_callback_.is_null())
9078 return error::kNoError;
9079
9080 return wait_sync_point_callback_.Run(c.sync_point) ?
9081 error::kNoError : error::kDeferCommandUntilLater;
9082}
9083
[email protected]882ba1e22012-03-08 19:02:539084bool GLES2DecoderImpl::GenQueriesEXTHelper(
9085 GLsizei n, const GLuint* client_ids) {
9086 for (GLsizei ii = 0; ii < n; ++ii) {
9087 if (query_manager_->GetQuery(client_ids[ii])) {
9088 return false;
9089 }
9090 }
[email protected]c45f1972012-03-14 07:27:369091 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
[email protected]882ba1e22012-03-08 19:02:539092 return true;
9093}
9094
9095void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9096 GLsizei n, const GLuint* client_ids) {
9097 for (GLsizei ii = 0; ii < n; ++ii) {
9098 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9099 if (query && !query->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:119100 if (query == state_.current_query.get()) {
[email protected]e259eb412012-10-13 05:47:249101 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539102 }
[email protected]c45f1972012-03-14 07:27:369103 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539104 query_manager_->RemoveQuery(client_ids[ii]);
9105 }
9106 }
9107}
9108
[email protected]22e3f552012-03-13 01:54:199109bool GLES2DecoderImpl::ProcessPendingQueries() {
9110 if (query_manager_.get() == NULL) {
9111 return false;
9112 }
[email protected]c45f1972012-03-14 07:27:369113 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:199114 current_decoder_error_ = error::kOutOfBounds;
9115 }
9116 return query_manager_->HavePendingQueries();
9117}
9118
[email protected]5a36dc132013-07-23 23:17:559119// Note that if there are no pending readpixels right now,
9120// this function will call the callback immediately.
9121void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
9122 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
9123 pending_readpixel_fences_.back()->callbacks.push_back(callback);
9124 } else {
9125 callback.Run();
9126 }
9127}
9128
9129void GLES2DecoderImpl::ProcessPendingReadPixels() {
9130 while (!pending_readpixel_fences_.empty() &&
9131 pending_readpixel_fences_.front()->fence->HasCompleted()) {
9132 std::vector<base::Closure> callbacks =
9133 pending_readpixel_fences_.front()->callbacks;
9134 pending_readpixel_fences_.pop();
9135 for (size_t i = 0; i < callbacks.size(); i++) {
9136 callbacks[i].Run();
9137 }
9138 }
9139}
9140
[email protected]2b1767cf2013-03-16 09:25:059141bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559142 return !pending_readpixel_fences_.empty() ||
9143 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059144}
9145
9146void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559147 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:489148 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:059149 return;
[email protected]b68b100752013-06-05 08:34:489150 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059151 ProcessFinishedAsyncTransfers();
9152}
9153
[email protected]882ba1e22012-03-08 19:02:539154error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359155 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539156 GLenum target = static_cast<GLenum>(c.target);
9157 GLuint client_id = static_cast<GLuint>(c.id);
9158 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9159 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9160
[email protected]c45f1972012-03-14 07:27:369161 switch (target) {
9162 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559163 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:319164 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
9165 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009166 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369167 break;
9168 default:
[email protected]62e155e2012-10-23 22:43:159169 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519170 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009171 GL_INVALID_OPERATION, "glBeginQueryEXT",
9172 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369173 return error::kNoError;
9174 }
9175 break;
[email protected]882ba1e22012-03-08 19:02:539176 }
9177
[email protected]5a36dc132013-07-23 23:17:559178 // TODO(hubbe): Make it possible to have one query per type running at the
9179 // same time.
[email protected]7cd76fd2013-06-02 21:11:119180 if (state_.current_query.get()) {
[email protected]ab09b612013-03-11 22:11:519181 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439182 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539183 return error::kNoError;
9184 }
9185
9186 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519187 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539188 return error::kNoError;
9189 }
9190
9191 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9192 if (!query) {
[email protected]c45f1972012-03-14 07:27:369193 // TODO(gman): Decide if we need this check.
9194 //
[email protected]882ba1e22012-03-08 19:02:539195 // Checks id was made by glGenQueries
[email protected]c45f1972012-03-14 07:27:369196 //
9197 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
9198 // for all Query ids but from the POV of the command buffer service maybe
9199 // you don't.
9200 //
9201 // The client can enforce this. I don't think the service cares.
9202 //
9203 // IdAllocatorInterface* id_allocator =
9204 // group_->GetIdAllocator(id_namespaces::kQueries);
9205 // if (!id_allocator->InUse(client_id)) {
[email protected]ab09b612013-03-11 22:11:519206 // LOCAL_SET_GL_ERROR(
9207 // GL_INVALID_OPERATION,
9208 // "glBeginQueryEXT", "id not made by glGenQueriesEXT");
[email protected]c45f1972012-03-14 07:27:369209 // return error::kNoError;
9210 // }
9211 query = query_manager_->CreateQuery(
9212 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539213 }
9214
[email protected]c45f1972012-03-14 07:27:369215 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519216 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439217 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539218 return error::kNoError;
9219 } else if (query->shm_id() != sync_shm_id ||
9220 query->shm_offset() != sync_shm_offset) {
9221 DLOG(ERROR) << "Shared memory used by query not the same as before";
9222 return error::kInvalidArguments;
9223 }
9224
[email protected]c45f1972012-03-14 07:27:369225 if (!query_manager_->BeginQuery(query)) {
9226 return error::kOutOfBounds;
9227 }
[email protected]882ba1e22012-03-08 19:02:539228
[email protected]e259eb412012-10-13 05:47:249229 state_.current_query = query;
[email protected]882ba1e22012-03-08 19:02:539230 return error::kNoError;
9231}
9232
9233error::Error GLES2DecoderImpl::HandleEndQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359234 uint32 immediate_data_size, const cmds::EndQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539235 GLenum target = static_cast<GLenum>(c.target);
9236 uint32 submit_count = static_cast<GLuint>(c.submit_count);
9237
[email protected]7cd76fd2013-06-02 21:11:119238 if (!state_.current_query.get()) {
[email protected]ab09b612013-03-11 22:11:519239 LOCAL_SET_GL_ERROR(
9240 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539241 return error::kNoError;
9242 }
[email protected]e259eb412012-10-13 05:47:249243 if (state_.current_query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519244 LOCAL_SET_GL_ERROR(
9245 GL_INVALID_OPERATION,
9246 "glEndQueryEXT", "target does not match active query");
[email protected]882ba1e22012-03-08 19:02:539247 return error::kNoError;
9248 }
[email protected]882ba1e22012-03-08 19:02:539249
[email protected]7cd76fd2013-06-02 21:11:119250 if (!query_manager_->EndQuery(state_.current_query.get(), submit_count)) {
[email protected]c45f1972012-03-14 07:27:369251 return error::kOutOfBounds;
9252 }
9253
[email protected]fe8d73c2013-02-16 22:37:329254 query_manager_->ProcessPendingTransferQueries();
9255
[email protected]e259eb412012-10-13 05:47:249256 state_.current_query = NULL;
[email protected]882ba1e22012-03-08 19:02:539257 return error::kNoError;
9258}
9259
[email protected]944b62f32012-09-27 02:20:469260bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9261 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469262 for (GLsizei ii = 0; ii < n; ++ii) {
9263 if (GetVertexAttribManager(client_ids[ii])) {
9264 return false;
9265 }
9266 }
[email protected]ab4fd7282012-10-12 16:25:579267
[email protected]62e155e2012-10-23 22:43:159268 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579269 // Emulated VAO
9270 for (GLsizei ii = 0; ii < n; ++ii) {
9271 CreateVertexAttribManager(client_ids[ii], 0);
9272 }
9273 } else {
[email protected]40d90a22013-04-09 03:39:559274 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:579275
9276 glGenVertexArraysOES(n, service_ids.get());
9277 for (GLsizei ii = 0; ii < n; ++ii) {
9278 CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
9279 }
[email protected]944b62f32012-09-27 02:20:469280 }
[email protected]ab4fd7282012-10-12 16:25:579281
[email protected]944b62f32012-09-27 02:20:469282 return true;
9283}
9284
9285void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9286 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469287 for (GLsizei ii = 0; ii < n; ++ii) {
9288 VertexAttribManager* vao =
9289 GetVertexAttribManager(client_ids[ii]);
9290 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:119291 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]e259eb412012-10-13 05:47:249292 state_.vertex_attrib_manager = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469293 }
9294 RemoveVertexAttribManager(client_ids[ii]);
9295 }
9296 }
9297}
9298
9299void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469300 VertexAttribManager* vao = NULL;
9301 GLuint service_id = 0;
9302 if (client_id != 0) {
9303 vao = GetVertexAttribManager(client_id);
9304 if (!vao) {
9305 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9306 // only allows names that have been previously generated. As such, we do
9307 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:519308 LOCAL_SET_GL_ERROR(
9309 GL_INVALID_OPERATION,
9310 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:469311 current_decoder_error_ = error::kNoError;
9312 return;
9313 } else {
9314 service_id = vao->service_id();
9315 }
[email protected]944b62f32012-09-27 02:20:469316 } else {
[email protected]7cd76fd2013-06-02 21:11:119317 vao = default_vertex_attrib_manager_.get();
[email protected]944b62f32012-09-27 02:20:469318 }
9319
[email protected]ab4fd7282012-10-12 16:25:579320 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:119321 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:249322 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:159323 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579324 EmulateVertexArrayState();
9325 } else {
9326 glBindVertexArrayOES(service_id);
9327 }
9328 }
9329}
9330
9331// Used when OES_vertex_array_object isn't natively supported
9332void GLES2DecoderImpl::EmulateVertexArrayState() {
9333 // Setup the Vertex attribute state
9334 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
9335 RestoreStateForAttrib(vv);
9336 }
9337
9338 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:219339 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:249340 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:579341 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9342 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:469343}
9344
9345bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469346 const VertexAttribManager* vao =
9347 GetVertexAttribManager(client_id);
9348 return vao && vao->IsValid() && !vao->IsDeleted();
9349}
9350
[email protected]b0af4f52011-09-28 22:04:429351error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM(
9352 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359353 const cmds::CreateStreamTextureCHROMIUM& c) {
[email protected]62e155e2012-10-23 22:43:159354 if (!features().chromium_stream_texture) {
[email protected]ab09b612013-03-11 22:11:519355 LOCAL_SET_GL_ERROR(
9356 GL_INVALID_OPERATION,
9357 "glOpenStreamTextureCHROMIUM", "not supported.");
[email protected]b0af4f52011-09-28 22:04:429358 return error::kNoError;
9359 }
9360
9361 uint32 client_id = c.client_id;
[email protected]ed9f9cd2013-02-27 21:12:359362 typedef cmds::CreateStreamTextureCHROMIUM::Result Result;
[email protected]b0af4f52011-09-28 22:04:429363 Result* result = GetSharedMemoryAs<Result*>(
9364 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9365
[email protected]e5081262012-01-05 23:09:039366 if (!result)
9367 return error::kOutOfBounds;
[email protected]b0af4f52011-09-28 22:04:429368 *result = GL_ZERO;
[email protected]370eaf12013-05-18 09:19:499369 TextureRef* texture_ref = texture_manager()->GetTexture(client_id);
9370 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519371 LOCAL_SET_GL_ERROR(
9372 GL_INVALID_VALUE,
9373 "glCreateStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429374 return error::kNoError;
9375 }
9376
[email protected]370eaf12013-05-18 09:19:499377 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079378 if (texture->IsStreamTexture()) {
[email protected]ab09b612013-03-11 22:11:519379 LOCAL_SET_GL_ERROR(
9380 GL_INVALID_OPERATION,
9381 "glCreateStreamTextureCHROMIUM", "is already a stream texture.");
[email protected]b0af4f52011-09-28 22:04:429382 return error::kNoError;
9383 }
9384
[email protected]02965c22013-03-09 02:40:079385 if (texture->target() && texture->target() != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:519386 LOCAL_SET_GL_ERROR(
9387 GL_INVALID_OPERATION,
9388 "glCreateStreamTextureCHROMIUM",
9389 "is already bound to incompatible target.");
[email protected]b0af4f52011-09-28 22:04:429390 return error::kNoError;
9391 }
9392
[email protected]4f9958142013-07-02 03:58:079393 if (!stream_texture_manager())
[email protected]b0af4f52011-09-28 22:04:429394 return error::kInvalidArguments;
9395
[email protected]4f9958142013-07-02 03:58:079396 GLuint object_id = stream_texture_manager()->CreateStreamTexture(
[email protected]02965c22013-03-09 02:40:079397 texture->service_id(), client_id);
[email protected]b0af4f52011-09-28 22:04:429398
9399 if (object_id) {
[email protected]370eaf12013-05-18 09:19:499400 texture_manager()->SetStreamTexture(texture_ref, true);
[email protected]b0af4f52011-09-28 22:04:429401 } else {
[email protected]ab09b612013-03-11 22:11:519402 LOCAL_SET_GL_ERROR(
9403 GL_OUT_OF_MEMORY,
9404 "glCreateStreamTextureCHROMIUM", "failed to create platform texture.");
[email protected]b0af4f52011-09-28 22:04:429405 }
9406
9407 *result = object_id;
9408 return error::kNoError;
9409}
9410
9411error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM(
9412 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359413 const cmds::DestroyStreamTextureCHROMIUM& c) {
[email protected]b0af4f52011-09-28 22:04:429414 GLuint client_id = c.texture;
[email protected]370eaf12013-05-18 09:19:499415 TextureRef* texture_ref = texture_manager()->GetTexture(client_id);
[email protected]4f9958142013-07-02 03:58:079416 if (texture_ref && texture_manager()->IsStreamTextureOwner(texture_ref)) {
9417 if (!stream_texture_manager())
[email protected]b0af4f52011-09-28 22:04:429418 return error::kInvalidArguments;
9419
[email protected]4f9958142013-07-02 03:58:079420 stream_texture_manager()->DestroyStreamTexture(texture_ref->service_id());
[email protected]370eaf12013-05-18 09:19:499421 texture_manager()->SetStreamTexture(texture_ref, false);
[email protected]b0af4f52011-09-28 22:04:429422 } else {
[email protected]ab09b612013-03-11 22:11:519423 LOCAL_SET_GL_ERROR(
9424 GL_INVALID_VALUE,
9425 "glDestroyStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429426 }
9427
9428 return error::kNoError;
9429}
9430
[email protected]e51bdf32011-11-23 22:21:469431#if defined(OS_MACOSX)
9432void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9433 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9434 texture_id);
9435 if (it != texture_to_io_surface_map_.end()) {
9436 // Found a previous IOSurface bound to this texture; release it.
9437 CFTypeRef surface = it->second;
9438 CFRelease(surface);
9439 texture_to_io_surface_map_.erase(it);
9440 }
9441}
9442#endif
9443
9444void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9445 GLenum target, GLsizei width, GLsizei height,
9446 GLuint io_surface_id, GLuint plane) {
9447#if defined(OS_MACOSX)
9448 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:519449 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439450 GL_INVALID_OPERATION,
9451 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:469452 return;
9453 }
9454
9455 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize();
9456 if (!surface_support) {
[email protected]ab09b612013-03-11 22:11:519457 LOCAL_SET_GL_ERROR(
9458 GL_INVALID_OPERATION,
9459 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6.");
[email protected]e51bdf32011-11-23 22:21:469460 return;
9461 }
9462
9463 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9464 // This might be supported in the future, and if we could require
9465 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9466 // could delete a lot of code. For now, perform strict validation so we
9467 // know what's going on.
[email protected]ab09b612013-03-11 22:11:519468 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469469 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439470 "glTexImageIOSurface2DCHROMIUM",
9471 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:469472 return;
9473 }
9474
[email protected]09d50362012-10-18 20:54:379475 // Default target might be conceptually valid, but disallow it to avoid
9476 // accidents.
[email protected]c986af502013-08-14 01:04:449477 TextureRef* texture_ref =
9478 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:499479 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519480 LOCAL_SET_GL_ERROR(
9481 GL_INVALID_OPERATION,
9482 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:469483 return;
9484 }
[email protected]e51bdf32011-11-23 22:21:469485
9486 // Look up the new IOSurface. Note that because of asynchrony
9487 // between processes this might fail; during live resizing the
9488 // plugin process might allocate and release an IOSurface before
9489 // this process gets a chance to look it up. Hold on to any old
9490 // IOSurface in this case.
9491 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id);
9492 if (!surface) {
[email protected]ab09b612013-03-11 22:11:519493 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439494 GL_INVALID_OPERATION,
9495 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:469496 return;
9497 }
9498
9499 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:499500 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:469501
9502 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9503 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:499504 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:469505
9506 CGLContextObj context =
9507 static_cast<CGLContextObj>(context_->GetHandle());
9508
9509 CGLError err = surface_support->CGLTexImageIOSurface2D(
9510 context,
9511 target,
9512 GL_RGBA,
9513 width,
9514 height,
9515 GL_BGRA,
9516 GL_UNSIGNED_INT_8_8_8_8_REV,
9517 surface,
9518 plane);
9519
9520 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:519521 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469522 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439523 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:469524 return;
9525 }
9526
9527 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499528 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:469529 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9530
9531#else
[email protected]ab09b612013-03-11 22:11:519532 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439533 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:469534#endif
9535}
9536
[email protected]97dc7cbe2011-12-06 17:26:179537static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9538 switch (internalformat) {
9539 case GL_RGB565:
9540 return GL_RGB;
9541 case GL_RGBA4:
9542 return GL_RGBA;
9543 case GL_RGB5_A1:
9544 return GL_RGBA;
9545 case GL_RGB8_OES:
9546 return GL_RGB;
9547 case GL_RGBA8_OES:
9548 return GL_RGBA;
9549 case GL_LUMINANCE8_ALPHA8_EXT:
9550 return GL_LUMINANCE_ALPHA;
9551 case GL_LUMINANCE8_EXT:
9552 return GL_LUMINANCE;
9553 case GL_ALPHA8_EXT:
9554 return GL_ALPHA;
9555 case GL_RGBA32F_EXT:
9556 return GL_RGBA;
9557 case GL_RGB32F_EXT:
9558 return GL_RGB;
9559 case GL_ALPHA32F_EXT:
9560 return GL_ALPHA;
9561 case GL_LUMINANCE32F_EXT:
9562 return GL_LUMINANCE;
9563 case GL_LUMINANCE_ALPHA32F_EXT:
9564 return GL_LUMINANCE_ALPHA;
9565 case GL_RGBA16F_EXT:
9566 return GL_RGBA;
9567 case GL_RGB16F_EXT:
9568 return GL_RGB;
9569 case GL_ALPHA16F_EXT:
9570 return GL_ALPHA;
9571 case GL_LUMINANCE16F_EXT:
9572 return GL_LUMINANCE;
9573 case GL_LUMINANCE_ALPHA16F_EXT:
9574 return GL_LUMINANCE_ALPHA;
9575 case GL_BGRA8_EXT:
9576 return GL_BGRA_EXT;
9577 default:
9578 return GL_NONE;
9579 }
9580}
9581
[email protected]43410e92012-04-20 17:06:289582void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:039583 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:549584 GLenum internal_format, GLenum dest_type) {
[email protected]370eaf12013-05-18 09:19:499585 TextureRef* dest_texture_ref = GetTexture(dest_id);
9586 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:289587
[email protected]370eaf12013-05-18 09:19:499588 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:519589 LOCAL_SET_GL_ERROR(
9590 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:289591 return;
9592 }
9593
9594 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:519595 LOCAL_SET_GL_ERROR(
9596 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:289597 return;
9598 }
9599
[email protected]370eaf12013-05-18 09:19:499600 Texture* source_texture = source_texture_ref->texture();
9601 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079602 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:259603 (source_texture->target() != GL_TEXTURE_2D &&
9604 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]3ecc1052013-09-26 08:59:009605 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
9606 "glCopyTextureCHROMIUM",
9607 "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:039608 return;
9609 }
9610
[email protected]43410e92012-04-20 17:06:289611 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:289612
[email protected]3ecc1052013-09-26 08:59:009613 if (source_texture->IsStreamTexture()) {
9614 DCHECK_EQ(source_texture->target(),
9615 static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES));
[email protected]4f9958142013-07-02 03:58:079616 DCHECK(stream_texture_manager());
[email protected]377976552013-05-14 23:32:569617 StreamTexture* stream_tex =
[email protected]4f9958142013-07-02 03:58:079618 stream_texture_manager()->LookupStreamTexture(
[email protected]377976552013-05-14 23:32:569619 source_texture->service_id());
9620 if (!stream_tex) {
9621 LOCAL_SET_GL_ERROR(
9622 GL_INVALID_VALUE,
9623 "glCopyTextureChromium", "Stream texture lookup failed");
9624 return;
9625 }
9626 gfx::Size size = stream_tex->GetSize();
9627 source_width = size.width();
9628 source_height = size.height();
9629 if (source_width <= 0 || source_height <= 0) {
9630 LOCAL_SET_GL_ERROR(
9631 GL_INVALID_VALUE,
9632 "glCopyTextureChromium", "invalid streamtexture size");
9633 return;
9634 }
[email protected]3ecc1052013-09-26 08:59:009635 } else {
9636 if (!source_texture->GetLevelSize(
9637 source_texture->target(), 0, &source_width, &source_height)) {
9638 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
9639 "glCopyTextureChromium",
9640 "source texture has no level 0");
9641 return;
9642 }
9643
9644 // Check that this type of texture is allowed.
9645 if (!texture_manager()->ValidForTarget(
9646 source_texture->target(), level, source_width, source_height, 1)) {
9647 LOCAL_SET_GL_ERROR(
9648 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
9649 return;
9650 }
[email protected]377976552013-05-14 23:32:569651 }
9652
[email protected]cf6b8f62012-05-25 21:43:379653 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9654 // needed because it takes 10s of milliseconds to initialize.
9655 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:519656 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:379657 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:279658 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:379659 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:519660 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:379661 return;
9662 }
9663
[email protected]a4a6bdd12013-04-19 20:46:549664 GLenum dest_type_previous;
[email protected]0a1e9ad2012-05-04 21:13:039665 GLenum dest_internal_format;
[email protected]02965c22013-03-09 02:40:079666 bool dest_level_defined = dest_texture->GetLevelSize(
9667 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:289668
[email protected]0a1e9ad2012-05-04 21:13:039669 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:549670 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:079671 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:039672 }
9673
9674 // Resize the destination texture to the dimensions of the source texture.
9675 if (!dest_level_defined || dest_width != source_width ||
9676 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:549677 dest_internal_format != internal_format ||
9678 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:289679 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:519680 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:079681 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:389682 glTexImage2D(
[email protected]43410e92012-04-20 17:06:289683 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:039684 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:519685 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:039686 if (error != GL_NO_ERROR) {
[email protected]ce296892013-10-24 22:04:369687 RestoreCurrentTexture2DBindings(&state_);
[email protected]43410e92012-04-20 17:06:289688 return;
[email protected]0a1e9ad2012-05-04 21:13:039689 }
[email protected]43410e92012-04-20 17:06:289690
9691 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499692 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:039693 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:259694 } else {
[email protected]02965c22013-03-09 02:40:079695 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:499696 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:289697 }
9698
[email protected]91c94eb2013-10-22 10:32:549699 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
9700
[email protected]5394a4102013-04-18 05:41:379701 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
9702 // before presenting.
9703 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9704 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
9705 // instead of using default matrix crbug.com/226218.
9706 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
9707 0.0f, 1.0f, 0.0f, 0.0f,
9708 0.0f, 0.0f, 1.0f, 0.0f,
9709 0.0f, 0.0f, 0.0f, 1.0f};
9710 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
9711 this,
9712 source_texture->target(),
9713 dest_texture->target(),
9714 source_texture->service_id(),
9715 dest_texture->service_id(), level,
9716 source_width, source_height,
9717 unpack_flip_y_,
9718 unpack_premultiply_alpha_,
9719 unpack_unpremultiply_alpha_,
9720 default_matrix);
9721 } else {
9722 copy_texture_CHROMIUM_->DoCopyTexture(
9723 this,
9724 source_texture->target(),
9725 dest_texture->target(),
9726 source_texture->service_id(),
9727 dest_texture->service_id(), level,
9728 source_width, source_height,
9729 unpack_flip_y_,
9730 unpack_premultiply_alpha_,
9731 unpack_unpremultiply_alpha_);
9732 }
[email protected]91c94eb2013-10-22 10:32:549733
9734 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:289735}
9736
[email protected]97dc7cbe2011-12-06 17:26:179737static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
9738 switch (internalformat) {
9739 case GL_RGB565:
9740 return GL_UNSIGNED_SHORT_5_6_5;
9741 case GL_RGBA4:
9742 return GL_UNSIGNED_SHORT_4_4_4_4;
9743 case GL_RGB5_A1:
9744 return GL_UNSIGNED_SHORT_5_5_5_1;
9745 case GL_RGB8_OES:
9746 return GL_UNSIGNED_BYTE;
9747 case GL_RGBA8_OES:
9748 return GL_UNSIGNED_BYTE;
9749 case GL_LUMINANCE8_ALPHA8_EXT:
9750 return GL_UNSIGNED_BYTE;
9751 case GL_LUMINANCE8_EXT:
9752 return GL_UNSIGNED_BYTE;
9753 case GL_ALPHA8_EXT:
9754 return GL_UNSIGNED_BYTE;
9755 case GL_RGBA32F_EXT:
9756 return GL_FLOAT;
9757 case GL_RGB32F_EXT:
9758 return GL_FLOAT;
9759 case GL_ALPHA32F_EXT:
9760 return GL_FLOAT;
9761 case GL_LUMINANCE32F_EXT:
9762 return GL_FLOAT;
9763 case GL_LUMINANCE_ALPHA32F_EXT:
9764 return GL_FLOAT;
9765 case GL_RGBA16F_EXT:
9766 return GL_HALF_FLOAT_OES;
9767 case GL_RGB16F_EXT:
9768 return GL_HALF_FLOAT_OES;
9769 case GL_ALPHA16F_EXT:
9770 return GL_HALF_FLOAT_OES;
9771 case GL_LUMINANCE16F_EXT:
9772 return GL_HALF_FLOAT_OES;
9773 case GL_LUMINANCE_ALPHA16F_EXT:
9774 return GL_HALF_FLOAT_OES;
9775 case GL_BGRA8_EXT:
9776 return GL_UNSIGNED_BYTE;
9777 default:
9778 return GL_NONE;
9779 }
9780}
9781
9782void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:449783 GLenum target,
9784 GLint levels,
9785 GLenum internal_format,
9786 GLsizei width,
9787 GLsizei height) {
[email protected]43ed3a72012-05-30 22:55:389788 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT");
[email protected]80eb6b52012-01-19 00:14:419789 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:009790 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:519791 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439792 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:179793 return;
9794 }
[email protected]c986af502013-08-14 01:04:449795 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9796 &state_, target);
[email protected]370eaf12013-05-18 09:19:499797 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519798 LOCAL_SET_GL_ERROR(
9799 GL_INVALID_OPERATION,
9800 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:179801 return;
9802 }
[email protected]370eaf12013-05-18 09:19:499803 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079804 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:449805 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:179806 }
[email protected]02965c22013-03-09 02:40:079807 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:519808 LOCAL_SET_GL_ERROR(
9809 GL_INVALID_OPERATION,
9810 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:179811 return;
9812 }
[email protected]7989c9e2013-01-23 06:39:269813
9814 GLenum format = ExtractFormatFromStorageFormat(internal_format);
9815 GLenum type = ExtractTypeFromStorageFormat(internal_format);
9816
9817 {
9818 GLsizei level_width = width;
9819 GLsizei level_height = height;
9820 uint32 estimated_size = 0;
9821 for (int ii = 0; ii < levels; ++ii) {
9822 uint32 level_size = 0;
9823 if (!GLES2Util::ComputeImageDataSizes(
9824 level_width, level_height, format, type, state_.unpack_alignment,
9825 &estimated_size, NULL, NULL) ||
9826 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519827 LOCAL_SET_GL_ERROR(
9828 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:269829 return;
9830 }
9831 level_width = std::max(1, level_width >> 1);
9832 level_height = std::max(1, level_height >> 1);
9833 }
9834 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:519835 LOCAL_SET_GL_ERROR(
9836 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:269837 return;
9838 }
9839 }
9840
[email protected]ab09b612013-03-11 22:11:519841 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:389842 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:519843 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:179844 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:159845 GLsizei level_width = width;
9846 GLsizei level_height = height;
9847 for (int ii = 0; ii < levels; ++ii) {
9848 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499849 texture_ref, target, ii, format,
9850 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:159851 level_width = std::max(1, level_width >> 1);
9852 level_height = std::max(1, level_height >> 1);
9853 }
[email protected]02965c22013-03-09 02:40:079854 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:179855 }
[email protected]97dc7cbe2011-12-06 17:26:179856}
[email protected]e51bdf32011-11-23 22:21:469857
[email protected]78b514b2012-05-01 21:50:599858error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359859 uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) {
[email protected]baed42c2013-10-01 05:06:359860 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:599861}
9862
9863void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
9864 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:029865 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:329866 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:029867 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
9868
[email protected]c986af502013-08-14 01:04:449869 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
9870 &state_, target);
[email protected]370eaf12013-05-18 09:19:499871 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519872 LOCAL_SET_GL_ERROR(
9873 GL_INVALID_OPERATION,
9874 "glProduceTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599875 return;
9876 }
9877
[email protected]62e65f02013-05-29 22:28:109878 Texture* produced = texture_manager()->Produce(texture_ref);
9879 if (!produced) {
[email protected]ab09b612013-03-11 22:11:519880 LOCAL_SET_GL_ERROR(
9881 GL_INVALID_OPERATION,
9882 "glProduceTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:599883 return;
9884 }
9885
9886 if (!group_->mailbox_manager()->ProduceTexture(
9887 target,
9888 *reinterpret_cast<const MailboxName*>(mailbox),
[email protected]62e65f02013-05-29 22:28:109889 produced)) {
[email protected]ab09b612013-03-11 22:11:519890 LOCAL_SET_GL_ERROR(
9891 GL_INVALID_OPERATION,
9892 "glProduceTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599893 return;
9894 }
[email protected]78b514b2012-05-01 21:50:599895}
9896
9897void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
9898 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:029899 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:329900 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:029901 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
9902
[email protected]62e65f02013-05-29 22:28:109903 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:449904 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:119905 if (!texture_ref.get()) {
9906 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
9907 "glConsumeTextureCHROMIUM",
9908 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:599909 return;
9910 }
[email protected]62e65f02013-05-29 22:28:109911 GLuint client_id = texture_ref->client_id();
9912 if (!client_id) {
9913 LOCAL_SET_GL_ERROR(
9914 GL_INVALID_OPERATION,
9915 "glConsumeTextureCHROMIUM", "unknown texture for target");
9916 return;
9917 }
9918 Texture* texture =
[email protected]78b514b2012-05-01 21:50:599919 group_->mailbox_manager()->ConsumeTexture(
9920 target,
[email protected]62e65f02013-05-29 22:28:109921 *reinterpret_cast<const MailboxName*>(mailbox));
9922 if (!texture) {
[email protected]ab09b612013-03-11 22:11:519923 LOCAL_SET_GL_ERROR(
9924 GL_INVALID_OPERATION,
9925 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:599926 return;
9927 }
[email protected]62e65f02013-05-29 22:28:109928 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:519929 LOCAL_SET_GL_ERROR(
9930 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:109931 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:599932 return;
9933 }
[email protected]62e65f02013-05-29 22:28:109934
9935 DeleteTexturesHelper(1, &client_id);
9936 texture_ref = texture_manager()->Consume(client_id, texture);
9937 glBindTexture(target, texture_ref->service_id());
9938
9939 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
9940 unit.bind_target = target;
9941 switch (target) {
9942 case GL_TEXTURE_2D:
9943 unit.bound_texture_2d = texture_ref;
9944 break;
9945 case GL_TEXTURE_CUBE_MAP:
9946 unit.bound_texture_cube_map = texture_ref;
9947 break;
9948 case GL_TEXTURE_EXTERNAL_OES:
9949 unit.bound_texture_external_oes = texture_ref;
9950 break;
9951 case GL_TEXTURE_RECTANGLE_ARB:
9952 unit.bound_texture_rectangle_arb = texture_ref;
9953 break;
9954 default:
9955 NOTREACHED(); // Validation should prevent us getting here.
9956 break;
9957 }
[email protected]78b514b2012-05-01 21:50:599958}
9959
[email protected]d2a0e1a2012-08-12 02:25:019960void GLES2DecoderImpl::DoInsertEventMarkerEXT(
9961 GLsizei length, const GLchar* marker) {
9962 if (!marker) {
9963 marker = "";
9964 }
9965 debug_marker_manager_.SetMarker(
9966 length ? std::string(marker, length) : std::string(marker));
9967}
9968
9969void GLES2DecoderImpl::DoPushGroupMarkerEXT(
9970 GLsizei length, const GLchar* marker) {
9971 if (!marker) {
9972 marker = "";
9973 }
9974 debug_marker_manager_.PushGroup(
9975 length ? std::string(marker, length) : std::string(marker));
9976}
9977
9978void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
9979 debug_marker_manager_.PopGroup();
9980}
9981
[email protected]09d50362012-10-18 20:54:379982void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
9983 GLenum target, GLint image_id) {
9984 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
9985 if (target != GL_TEXTURE_2D) {
9986 // This might be supported in the future.
[email protected]ab09b612013-03-11 22:11:519987 LOCAL_SET_GL_ERROR(
[email protected]09d50362012-10-18 20:54:379988 GL_INVALID_OPERATION,
9989 "glBindTexImage2DCHROMIUM", "requires TEXTURE_2D target");
9990 return;
9991 }
9992
9993 // Default target might be conceptually valid, but disallow it to avoid
9994 // accidents.
[email protected]c986af502013-08-14 01:04:449995 TextureRef* texture_ref =
9996 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:499997 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519998 LOCAL_SET_GL_ERROR(
9999 GL_INVALID_OPERATION,
10000 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710001 return;
10002 }
10003
10004 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10005 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110006 LOCAL_SET_GL_ERROR(
10007 GL_INVALID_OPERATION,
10008 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710009 return;
10010 }
10011
[email protected]b8160812013-04-09 00:41:0410012 {
10013 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010014 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]b8160812013-04-09 00:41:0410015 if (!gl_image->BindTexImage()) {
10016 LOCAL_SET_GL_ERROR(
10017 GL_INVALID_OPERATION,
10018 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
10019 return;
10020 }
[email protected]09d50362012-10-18 20:54:3710021 }
10022
10023 gfx::Size size = gl_image->GetSize();
10024 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910025 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3710026 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4910027 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3710028}
10029
10030void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10031 GLenum target, GLint image_id) {
10032 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
10033 if (target != GL_TEXTURE_2D) {
10034 // This might be supported in the future.
[email protected]ab09b612013-03-11 22:11:5110035 LOCAL_SET_GL_ERROR(
[email protected]09d50362012-10-18 20:54:3710036 GL_INVALID_OPERATION,
10037 "glReleaseTexImage2DCHROMIUM", "requires TEXTURE_2D target");
10038 return;
10039 }
10040
10041 // Default target might be conceptually valid, but disallow it to avoid
10042 // accidents.
[email protected]c986af502013-08-14 01:04:4410043 TextureRef* texture_ref =
10044 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910045 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110046 LOCAL_SET_GL_ERROR(
10047 GL_INVALID_OPERATION,
10048 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710049 return;
10050 }
10051
10052 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10053 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110054 LOCAL_SET_GL_ERROR(
10055 GL_INVALID_OPERATION,
10056 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710057 return;
10058 }
10059
10060 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4910061 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3710062 return;
10063
[email protected]b8160812013-04-09 00:41:0410064 {
10065 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010066 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]b8160812013-04-09 00:41:0410067 gl_image->ReleaseTexImage();
10068 }
[email protected]09d50362012-10-18 20:54:3710069
10070 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910071 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3710072 GL_RGBA, GL_UNSIGNED_BYTE, false);
10073}
[email protected]d2a0e1a2012-08-12 02:25:0110074
[email protected]94307712012-11-16 23:26:1110075error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510076 uint32 immediate_data_size, const cmds::TraceBeginCHROMIUM& c) {
[email protected]94307712012-11-16 23:26:1110077 Bucket* bucket = GetBucket(c.bucket_id);
10078 if (!bucket || bucket->size() == 0) {
10079 return error::kInvalidArguments;
10080 }
10081 std::string command_name;
10082 if (!bucket->GetAsString(&command_name)) {
10083 return error::kInvalidArguments;
10084 }
[email protected]fb97b662013-02-20 23:02:1410085 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
10086 if (!gpu_tracer_->Begin(command_name)) {
[email protected]ab09b612013-03-11 22:11:5110087 LOCAL_SET_GL_ERROR(
10088 GL_INVALID_OPERATION,
10089 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1410090 return error::kNoError;
10091 }
[email protected]94307712012-11-16 23:26:1110092 return error::kNoError;
10093}
10094
10095void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1410096 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5110097 LOCAL_SET_GL_ERROR(
10098 GL_INVALID_OPERATION,
10099 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1110100 return;
10101 }
[email protected]fb97b662013-02-20 23:02:1410102 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
10103 gpu_tracer_->End();
[email protected]94307712012-11-16 23:26:1110104}
10105
[email protected]2f143d482013-03-14 18:04:4910106void GLES2DecoderImpl::DoDrawBuffersEXT(
10107 GLsizei count, const GLenum* bufs) {
10108 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10109 LOCAL_SET_GL_ERROR(
10110 GL_INVALID_VALUE,
10111 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10112 return;
10113 }
10114
10115 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10116 if (framebuffer) {
10117 for (GLsizei i = 0; i < count; ++i) {
10118 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10119 bufs[i] != GL_NONE) {
10120 LOCAL_SET_GL_ERROR(
10121 GL_INVALID_OPERATION,
10122 "glDrawBuffersEXT",
10123 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10124 return;
10125 }
10126 }
10127 glDrawBuffersARB(count, bufs);
10128 framebuffer->SetDrawBuffers(count, bufs);
10129 } else { // backbuffer
10130 if (count > 1 ||
10131 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10132 LOCAL_SET_GL_ERROR(
10133 GL_INVALID_OPERATION,
10134 "glDrawBuffersEXT",
10135 "more than one buffer or bufs not GL_NONE or GL_BACK");
10136 return;
10137 }
10138 GLenum mapped_buf = bufs[0];
10139 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10140 bufs[0] == GL_BACK) {
10141 mapped_buf = GL_COLOR_ATTACHMENT0;
10142 }
10143 glDrawBuffersARB(count, &mapped_buf);
10144 group_->set_draw_buffer(bufs[0]);
10145 }
10146}
10147
[email protected]32145a92012-12-17 09:01:5910148bool GLES2DecoderImpl::ValidateAsyncTransfer(
10149 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4710150 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5910151 GLenum target,
10152 GLint level,
10153 const void * data) {
10154 // We only support async uploads to 2D textures for now.
10155 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110156 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910157 return false;
10158 }
10159 // We only support uploads to level zero for now.
10160 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110161 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910162 return false;
10163 }
10164 // A transfer buffer must be bound, even for asyncTexImage2D.
10165 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110166 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910167 return false;
10168 }
10169 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4710170 if (!texture_ref ||
10171 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5110172 LOCAL_SET_GL_ERROR(
10173 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910174 function_name, "transfer already in progress");
10175 return false;
10176 }
10177 return true;
10178}
10179
[email protected]69023942012-11-30 19:57:1610180error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510181 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610182 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610183 GLenum target = static_cast<GLenum>(c.target);
10184 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4410185 // TODO(kloveless): Change HandleAsyncTexImage2DCHROMIUM command to use
10186 // unsigned integer for internalformat.
10187 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1610188 GLsizei width = static_cast<GLsizei>(c.width);
10189 GLsizei height = static_cast<GLsizei>(c.height);
10190 GLint border = static_cast<GLint>(c.border);
10191 GLenum format = static_cast<GLenum>(c.format);
10192 GLenum type = static_cast<GLenum>(c.type);
10193 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10194 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10195 uint32 pixels_size;
[email protected]32145a92012-12-17 09:01:5910196
10197 // TODO(epenner): Move this and copies of this memory validation
10198 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1610199 if (!GLES2Util::ComputeImageDataSizes(
10200 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
10201 NULL)) {
10202 return error::kOutOfBounds;
10203 }
10204 const void* pixels = NULL;
10205 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
10206 pixels = GetSharedMemoryAs<const void*>(
10207 pixels_shm_id, pixels_shm_offset, pixels_size);
10208 if (!pixels) {
10209 return error::kOutOfBounds;
10210 }
10211 }
10212
[email protected]c986af502013-08-14 01:04:4410213 TextureManager::DoTextImage2DArguments args = {
10214 target, level, internal_format, width, height, border, format, type,
10215 pixels, pixels_size};
10216 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5910217 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4410218 if (!texture_manager()->ValidateTexImage2D(
10219 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5910220 return error::kNoError;
10221 }
10222
10223 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4910224 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910225 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710226 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910227 return error::kNoError;
10228
10229 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0710230 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5110231 LOCAL_SET_GL_ERROR(
10232 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910233 "glAsyncTexImage2DCHROMIUM", "already defined");
10234 return error::kNoError;
10235 }
10236
[email protected]7989c9e2013-01-23 06:39:2610237 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5110238 LOCAL_SET_GL_ERROR(
10239 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610240 return error::kNoError;
10241 }
10242
[email protected]32145a92012-12-17 09:01:5910243 // We know the memory/size is safe, so get the real shared memory since
10244 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110245 gpu::Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
[email protected]32145a92012-12-17 09:01:5910246 base::SharedMemory* shared_memory = buffer.shared_memory;
10247 uint32 shm_size = buffer.size;
10248 uint32 shm_data_offset = c.pixels_shm_offset;
10249 uint32 shm_data_size = pixels_size;
10250
[email protected]5b3a8e02013-03-13 05:36:4410251 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3810252 AsyncTexImage2DParams tex_params = {
10253 target, level, static_cast<GLenum>(internal_format),
10254 width, height, border, format, type};
10255 AsyncMemoryParams mem_params = {
10256 shared_memory, shm_size, shm_data_offset, shm_data_size};
[email protected]32145a92012-12-17 09:01:5910257
[email protected]5b3a8e02013-03-13 05:36:4410258 // Set up the async state if needed, and make the texture
10259 // immutable so the async state stays valid. The level info
10260 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1810261 AsyncPixelTransferDelegate* delegate =
10262 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
10263 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4410264 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5910265
[email protected]896425e2013-06-12 17:27:1810266 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4410267 tex_params,
10268 mem_params,
10269 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4910270 // The callback is only invoked if the transfer delegate still
10271 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4410272 // ownership that both of these pointers are valid.
10273 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4910274 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4410275 tex_params));
[email protected]f598f422012-12-07 08:30:0310276 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610277}
10278
10279error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510280 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610281 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610282 GLenum target = static_cast<GLenum>(c.target);
10283 GLint level = static_cast<GLint>(c.level);
10284 GLint xoffset = static_cast<GLint>(c.xoffset);
10285 GLint yoffset = static_cast<GLint>(c.yoffset);
10286 GLsizei width = static_cast<GLsizei>(c.width);
10287 GLsizei height = static_cast<GLsizei>(c.height);
10288 GLenum format = static_cast<GLenum>(c.format);
10289 GLenum type = static_cast<GLenum>(c.type);
[email protected]32145a92012-12-17 09:01:5910290
10291 // TODO(epenner): Move this and copies of this memory validation
10292 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1610293 uint32 data_size;
10294 if (!GLES2Util::ComputeImageDataSizes(
10295 width, height, format, type, state_.unpack_alignment, &data_size,
10296 NULL, NULL)) {
10297 return error::kOutOfBounds;
10298 }
10299 const void* pixels = GetSharedMemoryAs<const void*>(
10300 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5910301
10302 // All the normal glTexSubImage2D validation.
10303 error::Error error = error::kNoError;
10304 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
10305 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
10306 return error;
[email protected]69023942012-11-30 19:57:1610307 }
10308
[email protected]32145a92012-12-17 09:01:5910309 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4410310 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10311 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910312 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910313 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710314 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910315 return error::kNoError;
10316
10317 // Guarantee async textures are always 'cleared' as follows:
10318 // - AsyncTexImage2D can not redefine an existing texture
10319 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
10320 // - AsyncTexSubImage2D clears synchronously if not already cleared.
10321 // - Textures become immutable after an async call.
10322 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0710323 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4910324 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
10325 target, level)) {
[email protected]ab09b612013-03-11 22:11:5110326 LOCAL_SET_GL_ERROR(
10327 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2510328 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5910329 return error::kNoError;
10330 }
10331 }
10332
10333 // We know the memory/size is safe, so get the real shared memory since
10334 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110335 gpu::Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
[email protected]32145a92012-12-17 09:01:5910336 base::SharedMemory* shared_memory = buffer.shared_memory;
10337 uint32 shm_size = buffer.size;
10338 uint32 shm_data_offset = c.data_shm_offset;
10339 uint32 shm_data_size = data_size;
10340
[email protected]5b3a8e02013-03-13 05:36:4410341 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0310342 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5910343 width, height, format, type};
[email protected]2a7568a2013-05-09 23:12:0310344 AsyncMemoryParams mem_params = {shared_memory, shm_size,
[email protected]32145a92012-12-17 09:01:5910345 shm_data_offset, shm_data_size};
[email protected]896425e2013-06-12 17:27:1810346 AsyncPixelTransferDelegate* delegate =
10347 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10348 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4410349 // TODO(epenner): We may want to enforce exclusive use
10350 // of async APIs in which case this should become an error,
10351 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0310352 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4410353 0, 0, 0, 0, 0, 0};
10354 texture->GetLevelSize(target, level, &define_params.width,
10355 &define_params.height);
10356 texture->GetLevelType(target, level, &define_params.type,
10357 &define_params.internal_format);
10358 // Set up the async state if needed, and make the texture
10359 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1810360 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4710361 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4410362 texture->SetImmutable(true);
10363 }
10364
[email protected]896425e2013-06-12 17:27:1810365 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5910366 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610367}
10368
[email protected]a00c1f742013-03-05 17:02:1610369error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
10370 uint32 immediate_data_size, const cmds::WaitAsyncTexImage2DCHROMIUM& c) {
10371 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10372 GLenum target = static_cast<GLenum>(c.target);
10373
10374 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110375 LOCAL_SET_GL_ERROR(
10376 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1610377 return error::kNoError;
10378 }
[email protected]c986af502013-08-14 01:04:4410379 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10380 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910381 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110382 LOCAL_SET_GL_ERROR(
10383 GL_INVALID_OPERATION,
10384 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1610385 return error::kNoError;
10386 }
[email protected]896425e2013-06-12 17:27:1810387 AsyncPixelTransferDelegate* delegate =
10388 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10389 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4910390 LOCAL_SET_GL_ERROR(
10391 GL_INVALID_OPERATION,
10392 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
10393 return error::kNoError;
10394 }
[email protected]896425e2013-06-12 17:27:1810395 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0910396 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1610397 return error::kNoError;
10398}
10399
[email protected]91c94eb2013-10-22 10:32:5410400void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
10401 TextureRef* texture_ref) {
10402 Texture* texture = texture_ref->texture();
10403 DoDidUseTexImageIfNeeded(texture, texture->target());
10404}
10405
[email protected]96449d2c2009-11-25 00:01:3210406// Include the auto-generated part of this file. We split this because it means
10407// we can easily edit the non-auto generated parts right here in this file
10408// instead of having to edit some template or the code generator.
10409#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
10410
10411} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2510412} // namespace gpu