blob: 36259a3013a4d895782dcb7bc40ab92776bdfb8d [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]b2e92592014-01-10 15:47:1520#include "base/debug/trace_event_synthetic_delay.h"
[email protected]3b63f8f42011-03-28 01:54:1521#include "base/memory/scoped_ptr.h"
[email protected]f4390962013-06-11 07:29:2222#include "base/strings/string_number_conversions.h"
[email protected]6d668892013-12-04 21:37:1223#include "base/strings/string_split.h"
[email protected]d37231fa2010-04-09 21:16:0224#include "build/build_config.h"
[email protected]96449d2c2009-11-25 00:01:3225#define GLES2_GPU_SERVICE 1
[email protected]f4390962013-06-11 07:29:2226#include "gpu/command_buffer/common/debug_marker_manager.h"
[email protected]96449d2c2009-11-25 00:01:3227#include "gpu/command_buffer/common/gles2_cmd_format.h"
28#include "gpu/command_buffer/common/gles2_cmd_utils.h"
[email protected]066849e32010-05-03 19:14:1029#include "gpu/command_buffer/common/id_allocator.h"
[email protected]2ad674132013-06-05 07:48:5130#include "gpu/command_buffer/common/mailbox.h"
[email protected]f4390962013-06-11 07:29:2231#include "gpu/command_buffer/service/async_pixel_transfer_delegate.h"
32#include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
[email protected]3916c97e2010-02-25 03:20:5033#include "gpu/command_buffer/service/buffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3234#include "gpu/command_buffer/service/cmd_buffer_engine.h"
[email protected]3916c97e2010-02-25 03:20:5035#include "gpu/command_buffer/service/context_group.h"
[email protected]e259eb412012-10-13 05:47:2436#include "gpu/command_buffer/service/context_state.h"
[email protected]d3eba342013-04-18 21:11:5037#include "gpu/command_buffer/service/error_state.h"
[email protected]915a59a12010-09-30 21:29:1138#include "gpu/command_buffer/service/feature_info.h"
[email protected]a25fa872010-03-25 02:57:5839#include "gpu/command_buffer/service/framebuffer_manager.h"
[email protected]96449d2c2009-11-25 00:01:3240#include "gpu/command_buffer/service/gl_utils.h"
[email protected]43410e92012-04-20 17:06:2841#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
[email protected]ba3176a2009-12-16 18:19:4642#include "gpu/command_buffer/service/gles2_cmd_validation.h"
[email protected]8f9b8dd2013-09-12 18:05:1343#include "gpu/command_buffer/service/gpu_state_tracer.h"
[email protected]e844ae22012-01-14 03:36:2644#include "gpu/command_buffer/service/gpu_switches.h"
[email protected]fb97b662013-02-20 23:02:1445#include "gpu/command_buffer/service/gpu_tracer.h"
[email protected]09d50362012-10-18 20:54:3746#include "gpu/command_buffer/service/image_manager.h"
[email protected]78b514b2012-05-01 21:50:5947#include "gpu/command_buffer/service/mailbox_manager.h"
[email protected]ff6493f2012-07-31 19:52:2548#include "gpu/command_buffer/service/memory_tracking.h"
[email protected]a93bb842010-02-16 23:03:4749#include "gpu/command_buffer/service/program_manager.h"
[email protected]882ba1e22012-03-08 19:02:5350#include "gpu/command_buffer/service/query_manager.h"
[email protected]a25fa872010-03-25 02:57:5851#include "gpu/command_buffer/service/renderbuffer_manager.h"
[email protected]a93bb842010-02-16 23:03:4752#include "gpu/command_buffer/service/shader_manager.h"
[email protected]a550584e2010-09-17 18:01:4553#include "gpu/command_buffer/service/shader_translator.h"
[email protected]87fb6ab2012-06-13 22:28:0454#include "gpu/command_buffer/service/shader_translator_cache.h"
[email protected]b0af4f52011-09-28 22:04:4255#include "gpu/command_buffer/service/stream_texture.h"
56#include "gpu/command_buffer/service/stream_texture_manager.h"
[email protected]a93bb842010-02-16 23:03:4757#include "gpu/command_buffer/service/texture_manager.h"
[email protected]944b62f32012-09-27 02:20:4658#include "gpu/command_buffer/service/vertex_array_manager.h"
[email protected]f4390962013-06-11 07:29:2259#include "gpu/command_buffer/service/vertex_attrib_manager.h"
[email protected]d8bc3ec2013-03-07 06:28:4060#include "ui/gl/gl_bindings.h"
[email protected]5a36dc132013-07-23 23:17:5561#include "ui/gl/gl_fence.h"
[email protected]09d50362012-10-18 20:54:3762#include "ui/gl/gl_image.h"
[email protected]c9e2cbbb2012-05-12 21:17:2763#include "ui/gl/gl_implementation.h"
64#include "ui/gl/gl_surface.h"
[email protected]423e644f2013-06-19 00:48:2765
[email protected]e51bdf32011-11-23 22:21:4666#if defined(OS_MACOSX)
[email protected]423e644f2013-06-19 00:48:2767#include "ui/gl/io_surface_support_mac.h"
[email protected]e51bdf32011-11-23 22:21:4668#endif
[email protected]de17df392010-04-23 21:09:4169
[email protected]6eb775352013-08-27 05:57:1670#if defined(OS_WIN)
71#include "base/win/win_util.h"
72#endif
73
[email protected]693ca512012-11-13 18:09:1374// TODO(zmo): we can't include "City.h" due to type def conflicts.
75extern uint64 CityHash64(const char*, size_t);
76
[email protected]a7a27ace2009-12-12 00:11:2577namespace gpu {
[email protected]96449d2c2009-11-25 00:01:3278namespace gles2 {
79
[email protected]f0d74742011-10-03 16:31:0480namespace {
[email protected]693ca512012-11-13 18:09:1381
[email protected]f0d74742011-10-03 16:31:0482static const char kOESDerivativeExtension[] = "GL_OES_standard_derivatives";
[email protected]70dc60932013-06-04 03:33:4983static const char kEXTFragDepthExtension[] = "GL_EXT_frag_depth";
[email protected]aff39ac82013-06-08 04:53:1384static const char kEXTDrawBuffersExtension[] = "GL_EXT_draw_buffers";
[email protected]693ca512012-11-13 18:09:1385
[email protected]3d944a82013-02-12 19:09:0286#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]693ca512012-11-13 18:09:1387khronos_uint64_t CityHashForAngle(const char* name, unsigned int len) {
88 return static_cast<khronos_uint64_t>(
89 CityHash64(name, static_cast<size_t>(len)));
90}
[email protected]3d944a82013-02-12 19:09:0291#endif
[email protected]693ca512012-11-13 18:09:1392
[email protected]448e459e2013-06-12 17:00:4193static bool PrecisionMeetsSpecForHighpFloat(GLint rangeMin,
94 GLint rangeMax,
95 GLint precision) {
96 return (rangeMin >= 62) && (rangeMax >= 62) && (precision >= 16);
97}
98
[email protected]8dc1bf92013-03-12 03:58:2199static void GetShaderPrecisionFormatImpl(GLenum shader_type,
100 GLenum precision_type,
101 GLint *range, GLint *precision) {
102 switch (precision_type) {
103 case GL_LOW_INT:
104 case GL_MEDIUM_INT:
105 case GL_HIGH_INT:
106 // These values are for a 32-bit twos-complement integer format.
107 range[0] = 31;
108 range[1] = 30;
109 *precision = 0;
110 break;
111 case GL_LOW_FLOAT:
112 case GL_MEDIUM_FLOAT:
113 case GL_HIGH_FLOAT:
114 // These values are for an IEEE single-precision floating-point format.
115 range[0] = 127;
116 range[1] = 127;
117 *precision = 23;
118 break;
119 default:
120 NOTREACHED();
121 break;
122 }
123
[email protected]8af4d5e2013-03-15 23:55:33124 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 &&
125 gfx::g_driver_gl.fn.glGetShaderPrecisionFormatFn) {
[email protected]8dc1bf92013-03-12 03:58:21126 // This function is sometimes defined even though it's really just
127 // a stub, so we need to set range and precision as if it weren't
128 // defined before calling it.
[email protected]501b57402013-03-14 22:21:44129 // On Mac OS with some GPUs, calling this generates a
130 // GL_INVALID_OPERATION error. Avoid calling it on non-GLES2
131 // platforms.
[email protected]8dc1bf92013-03-12 03:58:21132 glGetShaderPrecisionFormat(shader_type, precision_type,
133 range, precision);
[email protected]448e459e2013-06-12 17:00:41134
135 // TODO(brianderson): Make the following official workarounds.
136
137 // Some drivers have bugs where they report the ranges as a negative number.
138 // Taking the absolute value here shouldn't hurt because negative numbers
139 // aren't expected anyway.
140 range[0] = abs(range[0]);
141 range[1] = abs(range[1]);
142
143 // If the driver reports a precision for highp float that isn't actually
144 // highp, don't pretend like it's supported because shader compilation will
145 // fail anyway.
146 if (precision_type == GL_HIGH_FLOAT &&
147 !PrecisionMeetsSpecForHighpFloat(range[0], range[1], *precision)) {
148 range[0] = 0;
149 range[1] = 0;
150 *precision = 0;
151 }
[email protected]8dc1bf92013-03-12 03:58:21152 }
153}
154
[email protected]b04e24c2013-01-08 18:35:25155} // namespace
[email protected]f0d74742011-10-03 16:31:04156
[email protected]6217d392010-03-25 22:08:35157class GLES2DecoderImpl;
158
[email protected]ab09b612013-03-11 22:11:51159// Local versions of the SET_GL_ERROR macros
160#define LOCAL_SET_GL_ERROR(error, function_name, msg) \
[email protected]d3eba342013-04-18 21:11:50161 ERRORSTATE_SET_GL_ERROR(state_.GetErrorState(), error, function_name, msg)
[email protected]ab09b612013-03-11 22:11:51162#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label) \
[email protected]d3eba342013-04-18 21:11:50163 ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(state_.GetErrorState(), \
164 function_name, value, label)
[email protected]ab09b612013-03-11 22:11:51165#define LOCAL_SET_GL_ERROR_INVALID_PARAM(error, function_name, pname) \
[email protected]d3eba342013-04-18 21:11:50166 ERRORSTATE_SET_GL_ERROR_INVALID_PARAM(state_.GetErrorState(), error, \
167 function_name, pname)
[email protected]ab09b612013-03-11 22:11:51168#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
[email protected]d3eba342013-04-18 21:11:50169 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(state_.GetErrorState(), \
170 function_name)
[email protected]ab09b612013-03-11 22:11:51171#define LOCAL_PEEK_GL_ERROR(function_name) \
[email protected]d3eba342013-04-18 21:11:50172 ERRORSTATE_PEEK_GL_ERROR(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51173#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
[email protected]d3eba342013-04-18 21:11:50174 ERRORSTATE_CLEAR_REAL_GL_ERRORS(state_.GetErrorState(), function_name)
[email protected]ab09b612013-03-11 22:11:51175#define LOCAL_PERFORMANCE_WARNING(msg) \
176 PerformanceWarning(__FILE__, __LINE__, msg)
177#define LOCAL_RENDER_WARNING(msg) \
178 RenderWarning(__FILE__, __LINE__, msg)
179
[email protected]07f54fcc2009-12-22 02:46:30180// Check that certain assumptions the code makes are true. There are places in
181// the code where shared memory is passed direclty to GL. Example, glUniformiv,
182// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
183// a few others) are 32bits. If they are not 32bits the code will have to change
184// to call those GL functions with service side memory and then copy the results
185// to shared memory, converting the sizes.
186COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
187 GLint_not_same_size_as_uint32);
188COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
189 GLint_not_same_size_as_uint32);
[email protected]f7b85372010-02-03 01:11:37190COMPILE_ASSERT(sizeof(GLfloat) == sizeof(float), // NOLINT
191 GLfloat_not_same_size_as_float);
[email protected]07f54fcc2009-12-22 02:46:30192
[email protected]43f28f832010-02-03 02:28:48193// TODO(kbr): the use of this anonymous namespace core dumps the
194// linker on Mac OS X 10.6 when the symbol ordering file is used
195// namespace {
[email protected]96449d2c2009-11-25 00:01:32196
197// Returns the address of the first byte after a struct.
198template <typename T>
199const void* AddressAfterStruct(const T& pod) {
200 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
201}
202
[email protected]07f54fcc2009-12-22 02:46:30203// Returns the address of the frst byte after the struct or NULL if size >
204// immediate_data_size.
[email protected]96449d2c2009-11-25 00:01:32205template <typename RETURN_TYPE, typename COMMAND_TYPE>
[email protected]07f54fcc2009-12-22 02:46:30206RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
207 uint32 size,
208 uint32 immediate_data_size) {
209 return (size <= immediate_data_size) ?
210 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
211 NULL;
[email protected]96449d2c2009-11-25 00:01:32212}
213
[email protected]07f54fcc2009-12-22 02:46:30214// Computes the data size for certain gl commands like glUniform.
[email protected]a76b0052010-03-05 00:33:18215bool ComputeDataSize(
[email protected]96449d2c2009-11-25 00:01:32216 GLuint count,
217 size_t size,
[email protected]a76b0052010-03-05 00:33:18218 unsigned int elements_per_unit,
219 uint32* dst) {
220 uint32 value;
221 if (!SafeMultiplyUint32(count, size, &value)) {
222 return false;
223 }
224 if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
225 return false;
226 }
227 *dst = value;
228 return true;
[email protected]96449d2c2009-11-25 00:01:32229}
230
231// A struct to hold info about each command.
232struct CommandInfo {
[email protected]cac16542014-01-15 17:53:51233 uint8 arg_flags; // How to handle the arguments for this command
234 uint8 cmd_flags; // How to handle this command
235 uint16 arg_count; // How many arguments are expected for this command.
[email protected]96449d2c2009-11-25 00:01:32236};
237
[email protected]cac16542014-01-15 17:53:51238// cmds::name::cmd_flags,
[email protected]96449d2c2009-11-25 00:01:32239// A table of CommandInfo for all the commands.
240const CommandInfo g_command_info[] = {
[email protected]ed9f9cd2013-02-27 21:12:35241 #define GLES2_CMD_OP(name) { \
242 cmds::name::kArgFlags, \
[email protected]cac16542014-01-15 17:53:51243 cmds::name::cmd_flags, \
244 sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */
[email protected]96449d2c2009-11-25 00:01:32245
246 GLES2_COMMAND_LIST(GLES2_CMD_OP)
247
248 #undef GLES2_CMD_OP
249};
250
[email protected]258a3313f2011-10-18 20:13:57251// Return true if a character belongs to the ASCII subset as defined in
252// GLSL ES 1.0 spec section 3.1.
253static bool CharacterIsValidForGLES(unsigned char c) {
254 // Printing characters are valid except " $ ` @ \ ' DEL.
255 if (c >= 32 && c <= 126 &&
256 c != '"' &&
257 c != '$' &&
258 c != '`' &&
259 c != '@' &&
260 c != '\\' &&
261 c != '\'') {
262 return true;
263 }
264 // Horizontal tab, line feed, vertical tab, form feed, carriage return
265 // are also valid.
266 if (c >= 9 && c <= 13) {
267 return true;
268 }
269
270 return false;
271}
272
273static bool StringIsValidForGLES(const char* str) {
274 for (; *str; ++str) {
275 if (!CharacterIsValidForGLES(*str)) {
276 return false;
277 }
278 }
279 return true;
280}
281
[email protected]297ca1c2011-06-20 23:08:46282// Wrapper for glEnable/glDisable that doesn't suck.
283static void EnableDisable(GLenum pname, bool enable) {
284 if (enable) {
285 glEnable(pname);
286 } else {
287 glDisable(pname);
288 }
289}
290
[email protected]6217d392010-03-25 22:08:35291// This class prevents any GL errors that occur when it is in scope from
292// being reported to the client.
293class ScopedGLErrorSuppressor {
294 public:
[email protected]ab09b612013-03-11 22:11:51295 explicit ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:30296 const char* function_name, ErrorState* error_state);
[email protected]6217d392010-03-25 22:08:35297 ~ScopedGLErrorSuppressor();
298 private:
[email protected]ab09b612013-03-11 22:11:51299 const char* function_name_;
[email protected]40621eb52013-10-08 15:40:30300 ErrorState* error_state_;
[email protected]6217d392010-03-25 22:08:35301 DISALLOW_COPY_AND_ASSIGN(ScopedGLErrorSuppressor);
302};
303
304// Temporarily changes a decoder's bound 2D texture and restore it when this
305// object goes out of scope. Also temporarily switches to using active texture
306// unit zero in case the client has changed that to something invalid.
307class ScopedTexture2DBinder {
308 public:
[email protected]ce296892013-10-24 22:04:36309 ScopedTexture2DBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35310 ~ScopedTexture2DBinder();
311
312 private:
[email protected]ce296892013-10-24 22:04:36313 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35314 DISALLOW_COPY_AND_ASSIGN(ScopedTexture2DBinder);
315};
316
317// Temporarily changes a decoder's bound render buffer and restore it when this
318// object goes out of scope.
319class ScopedRenderBufferBinder {
320 public:
[email protected]18e785a2013-10-09 03:29:41321 ScopedRenderBufferBinder(ContextState* state, GLuint id);
[email protected]6217d392010-03-25 22:08:35322 ~ScopedRenderBufferBinder();
323
324 private:
[email protected]18e785a2013-10-09 03:29:41325 ContextState* state_;
[email protected]6217d392010-03-25 22:08:35326 DISALLOW_COPY_AND_ASSIGN(ScopedRenderBufferBinder);
327};
328
329// Temporarily changes a decoder's bound frame buffer and restore it when this
330// object goes out of scope.
331class ScopedFrameBufferBinder {
332 public:
333 ScopedFrameBufferBinder(GLES2DecoderImpl* decoder, GLuint id);
334 ~ScopedFrameBufferBinder();
335
336 private:
337 GLES2DecoderImpl* decoder_;
338 DISALLOW_COPY_AND_ASSIGN(ScopedFrameBufferBinder);
339};
340
[email protected]34ff8b0c2010-10-01 20:06:02341// Temporarily changes a decoder's bound frame buffer to a resolved version of
[email protected]c0701082011-04-20 00:34:52342// the multisampled offscreen render buffer if that buffer is multisampled, and,
[email protected]de26b3c2011-08-03 21:54:27343// if it is bound or enforce_internal_framebuffer is true. If internal is
344// true, the resolved framebuffer is not visible to the parent.
[email protected]34ff8b0c2010-10-01 20:06:02345class ScopedResolvedFrameBufferBinder {
346 public:
[email protected]e7e38032011-07-26 17:25:25347 ScopedResolvedFrameBufferBinder(GLES2DecoderImpl* decoder,
[email protected]de26b3c2011-08-03 21:54:27348 bool enforce_internal_framebuffer,
349 bool internal);
[email protected]34ff8b0c2010-10-01 20:06:02350 ~ScopedResolvedFrameBufferBinder();
351
352 private:
353 GLES2DecoderImpl* decoder_;
354 bool resolve_and_bind_;
355 DISALLOW_COPY_AND_ASSIGN(ScopedResolvedFrameBufferBinder);
356};
357
[email protected]6217d392010-03-25 22:08:35358// Encapsulates an OpenGL texture.
[email protected]ed9f9cd2013-02-27 21:12:35359class BackTexture {
[email protected]6217d392010-03-25 22:08:35360 public:
[email protected]ce296892013-10-24 22:04:36361 explicit BackTexture(MemoryTracker* memory_tracker, ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35362 ~BackTexture();
[email protected]6217d392010-03-25 22:08:35363
364 // Create a new render texture.
365 void Create();
366
367 // Set the initial size and format of a render texture or resize it.
[email protected]678a73f2012-12-19 19:22:09368 bool AllocateStorage(const gfx::Size& size, GLenum format, bool zero);
[email protected]6217d392010-03-25 22:08:35369
370 // Copy the contents of the currently bound frame buffer.
[email protected]3a4d0c52011-06-29 23:11:58371 void Copy(const gfx::Size& size, GLenum format);
[email protected]6217d392010-03-25 22:08:35372
373 // Destroy the render texture. This must be explicitly called before
374 // destroying this object.
375 void Destroy();
376
[email protected]97872062010-11-03 19:07:05377 // Invalidate the texture. This can be used when a context is lost and it is
378 // not possible to make it current in order to free the resource.
379 void Invalidate();
380
[email protected]6217d392010-03-25 22:08:35381 GLuint id() const {
382 return id_;
383 }
384
[email protected]d37231fa2010-04-09 21:16:02385 gfx::Size size() const {
386 return size_;
387 }
388
[email protected]1078f912011-12-23 13:12:14389 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25390 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14391 }
392
[email protected]6217d392010-03-25 22:08:35393 private:
[email protected]ff6493f2012-07-31 19:52:25394 MemoryTypeTracker memory_tracker_;
[email protected]ce296892013-10-24 22:04:36395 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48396 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35397 GLuint id_;
[email protected]d37231fa2010-04-09 21:16:02398 gfx::Size size_;
[email protected]ed9f9cd2013-02-27 21:12:35399 DISALLOW_COPY_AND_ASSIGN(BackTexture);
[email protected]6217d392010-03-25 22:08:35400};
401
402// Encapsulates an OpenGL render buffer of any format.
[email protected]ed9f9cd2013-02-27 21:12:35403class BackRenderbuffer {
[email protected]6217d392010-03-25 22:08:35404 public:
[email protected]d5a28e452013-10-10 01:01:40405 explicit BackRenderbuffer(
406 RenderbufferManager* renderbuffer_manager,
407 MemoryTracker* memory_tracker,
408 ContextState* state);
[email protected]ed9f9cd2013-02-27 21:12:35409 ~BackRenderbuffer();
[email protected]6217d392010-03-25 22:08:35410
411 // Create a new render buffer.
412 void Create();
413
414 // Set the initial size and format of a render buffer or resize it.
[email protected]f42f05b2013-11-15 21:46:18415 bool AllocateStorage(const FeatureInfo* feature_info,
416 const gfx::Size& size,
417 GLenum format,
418 GLsizei samples);
[email protected]6217d392010-03-25 22:08:35419
420 // Destroy the render buffer. This must be explicitly called before destroying
421 // this object.
422 void Destroy();
423
[email protected]97872062010-11-03 19:07:05424 // Invalidate the render buffer. This can be used when a context is lost and
425 // it is not possible to make it current in order to free the resource.
426 void Invalidate();
427
[email protected]6217d392010-03-25 22:08:35428 GLuint id() const {
429 return id_;
430 }
431
[email protected]1078f912011-12-23 13:12:14432 size_t estimated_size() const {
[email protected]ff6493f2012-07-31 19:52:25433 return memory_tracker_.GetMemRepresented();
[email protected]1078f912011-12-23 13:12:14434 }
435
[email protected]6217d392010-03-25 22:08:35436 private:
[email protected]d5a28e452013-10-10 01:01:40437 RenderbufferManager* renderbuffer_manager_;
[email protected]ff6493f2012-07-31 19:52:25438 MemoryTypeTracker memory_tracker_;
[email protected]d5a28e452013-10-10 01:01:40439 ContextState* state_;
[email protected]68e81a4a62012-12-13 01:16:48440 size_t bytes_allocated_;
[email protected]6217d392010-03-25 22:08:35441 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35442 DISALLOW_COPY_AND_ASSIGN(BackRenderbuffer);
[email protected]6217d392010-03-25 22:08:35443};
444
445// Encapsulates an OpenGL frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35446class BackFramebuffer {
[email protected]6217d392010-03-25 22:08:35447 public:
[email protected]ed9f9cd2013-02-27 21:12:35448 explicit BackFramebuffer(GLES2DecoderImpl* decoder);
449 ~BackFramebuffer();
[email protected]6217d392010-03-25 22:08:35450
451 // Create a new frame buffer.
452 void Create();
453
454 // Attach a color render buffer to a frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35455 void AttachRenderTexture(BackTexture* texture);
[email protected]6217d392010-03-25 22:08:35456
[email protected]b9363b22010-06-09 22:06:15457 // Attach a render buffer to a frame buffer. Note that this unbinds any
458 // currently bound frame buffer.
[email protected]ed9f9cd2013-02-27 21:12:35459 void AttachRenderBuffer(GLenum target, BackRenderbuffer* render_buffer);
[email protected]6217d392010-03-25 22:08:35460
[email protected]6217d392010-03-25 22:08:35461 // Destroy the frame buffer. This must be explicitly called before destroying
462 // this object.
463 void Destroy();
464
[email protected]97872062010-11-03 19:07:05465 // Invalidate the frame buffer. This can be used when a context is lost and it
466 // is not possible to make it current in order to free the resource.
467 void Invalidate();
468
[email protected]6217d392010-03-25 22:08:35469 // See glCheckFramebufferStatusEXT.
470 GLenum CheckStatus();
471
472 GLuint id() const {
473 return id_;
474 }
475
476 private:
477 GLES2DecoderImpl* decoder_;
478 GLuint id_;
[email protected]ed9f9cd2013-02-27 21:12:35479 DISALLOW_COPY_AND_ASSIGN(BackFramebuffer);
[email protected]6217d392010-03-25 22:08:35480};
[email protected]34ff8b0c2010-10-01 20:06:02481
[email protected]5a36dc132013-07-23 23:17:55482struct FenceCallback {
483 explicit FenceCallback()
484 : fence(gfx::GLFence::Create()) {
485 DCHECK(fence);
486 }
487 void AddCallback(base::Closure cb) {
488 callbacks.push_back(cb);
489 }
490 std::vector<base::Closure> callbacks;
491 scoped_ptr<gfx::GLFence> fence;
492};
493
[email protected]43f28f832010-02-03 02:28:48494// } // anonymous namespace.
[email protected]96449d2c2009-11-25 00:01:32495
[email protected]ddb1e5a2010-12-13 20:10:45496bool GLES2Decoder::GetServiceTextureId(uint32 client_texture_id,
497 uint32* service_texture_id) {
498 return false;
499}
500
[email protected]a3ded6d2010-10-19 06:44:39501GLES2Decoder::GLES2Decoder()
[email protected]55e136f2013-04-03 18:50:06502 : initialized_(false),
503 debug_(false),
[email protected]1d82e822013-04-10 21:32:32504 log_commands_(false) {
[email protected]96449d2c2009-11-25 00:01:32505}
506
[email protected]3916c97e2010-02-25 03:20:50507GLES2Decoder::~GLES2Decoder() {
508}
509
[email protected]cac16542014-01-15 17:53:51510void GLES2Decoder::BeginDecoding() {}
511
512void GLES2Decoder::EndDecoding() {}
513
[email protected]f39f4b3f2010-05-12 17:04:08514// This class implements GLES2Decoder so we don't have to expose all the GLES2
515// cmd stuff to outside this class.
[email protected]91c94eb2013-10-22 10:32:54516class GLES2DecoderImpl : public GLES2Decoder,
517 public FramebufferManager::TextureDetachObserver {
[email protected]f39f4b3f2010-05-12 17:04:08518 public:
[email protected]476ccb72012-12-06 15:52:52519 // Used by PrepForSetUniformByLocation to validate types.
520 struct BaseUniformInfo {
521 const GLenum* const valid_types;
522 size_t num_valid_types;
523 };
524
[email protected]aa7666122011-09-02 19:45:52525 explicit GLES2DecoderImpl(ContextGroup* group);
[email protected]b8e97b62012-09-30 15:09:00526 virtual ~GLES2DecoderImpl();
[email protected]f39f4b3f2010-05-12 17:04:08527
[email protected]96449d2c2009-11-25 00:01:32528 // Overridden from AsyncAPIInterface.
[email protected]f7a64ee2010-02-01 22:24:14529 virtual Error DoCommand(unsigned int command,
[email protected]3916c97e2010-02-25 03:20:50530 unsigned int arg_count,
[email protected]b8e97b62012-09-30 15:09:00531 const void* args) OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32532
533 // Overridden from AsyncAPIInterface.
[email protected]b8e97b62012-09-30 15:09:00534 virtual const char* GetCommandName(unsigned int command_id) const OVERRIDE;
[email protected]96449d2c2009-11-25 00:01:32535
536 // Overridden from GLES2Decoder.
[email protected]fbe20372011-06-01 01:46:38537 virtual bool Initialize(const scoped_refptr<gfx::GLSurface>& surface,
538 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:23539 bool offscreen,
[email protected]6217d392010-03-25 22:08:35540 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:29541 const DisallowedFeatures& disallowed_features,
[email protected]b8e97b62012-09-30 15:09:00542 const std::vector<int32>& attribs) OVERRIDE;
543 virtual void Destroy(bool have_context) OVERRIDE;
[email protected]63c9b052012-05-17 18:27:38544 virtual void SetSurface(
545 const scoped_refptr<gfx::GLSurface>& surface) OVERRIDE;
[email protected]2ad674132013-06-05 07:48:51546 virtual bool ProduceFrontBuffer(const Mailbox& mailbox) OVERRIDE;
[email protected]b8e97b62012-09-30 15:09:00547 virtual bool ResizeOffscreenFrameBuffer(const gfx::Size& size) OVERRIDE;
[email protected]9a5afa432011-07-22 18:16:39548 void UpdateParentTextureInfo();
[email protected]b8e97b62012-09-30 15:09:00549 virtual bool MakeCurrent() OVERRIDE;
550 virtual void ReleaseCurrent() OVERRIDE;
551 virtual GLES2Util* GetGLES2Util() OVERRIDE { return &util_; }
552 virtual gfx::GLContext* GetGLContext() OVERRIDE { return context_.get(); }
553 virtual ContextGroup* GetContextGroup() OVERRIDE { return group_.get(); }
[email protected]6d668892013-12-04 21:37:12554 virtual Capabilities GetCapabilities() OVERRIDE;
[email protected]1868a342012-11-07 15:56:02555 virtual void RestoreState() const OVERRIDE;
[email protected]29a4d902013-02-26 20:18:06556
557 virtual void RestoreActiveTexture() const OVERRIDE {
558 state_.RestoreActiveTexture();
559 }
[email protected]217004512013-05-10 21:25:55560 virtual void RestoreAllTextureUnitBindings() const OVERRIDE {
561 state_.RestoreAllTextureUnitBindings();
562 }
[email protected]29a4d902013-02-26 20:18:06563 virtual void RestoreAttribute(unsigned index) const OVERRIDE {
564 state_.RestoreAttribute(index);
565 }
566 virtual void RestoreBufferBindings() const OVERRIDE {
567 state_.RestoreBufferBindings();
568 }
569 virtual void RestoreGlobalState() const OVERRIDE {
570 state_.RestoreGlobalState();
571 }
572 virtual void RestoreProgramBindings() const OVERRIDE {
573 state_.RestoreProgramBindings();
574 }
575 virtual void RestoreRenderbufferBindings() const OVERRIDE {
576 state_.RestoreRenderbufferBindings();
577 }
578 virtual void RestoreTextureUnitBindings(unsigned unit) const OVERRIDE {
579 state_.RestoreTextureUnitBindings(unit);
580 }
581 virtual void RestoreFramebufferBindings() const OVERRIDE;
582 virtual void RestoreTextureState(unsigned service_id) const OVERRIDE;
583
[email protected]b8e97b62012-09-30 15:09:00584 virtual QueryManager* GetQueryManager() OVERRIDE {
585 return query_manager_.get();
586 }
587 virtual VertexArrayManager* GetVertexArrayManager() OVERRIDE {
[email protected]944b62f32012-09-27 02:20:46588 return vertex_array_manager_.get();
589 }
[email protected]b8e97b62012-09-30 15:09:00590 virtual bool ProcessPendingQueries() OVERRIDE;
[email protected]2b1767cf2013-03-16 09:25:05591 virtual bool HasMoreIdleWork() OVERRIDE;
592 virtual void PerformIdleWork() OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48593
[email protected]5a36dc132013-07-23 23:17:55594 virtual void WaitForReadPixels(base::Closure callback) OVERRIDE;
595
[email protected]9d37f062011-11-22 01:24:52596 virtual void SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:07597 const base::Callback<void(gfx::Size, float)>& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00598
[email protected]1d82e822013-04-10 21:32:32599 virtual Logger* GetLogger() OVERRIDE;
[email protected]cac16542014-01-15 17:53:51600
601 virtual void BeginDecoding() OVERRIDE;
602 virtual void EndDecoding() OVERRIDE;
603
[email protected]d3eba342013-04-18 21:11:50604 virtual ErrorState* GetErrorState() OVERRIDE;
[email protected]1d82e822013-04-10 21:32:32605
[email protected]e3932abb2013-03-13 00:01:37606 virtual void SetShaderCacheCallback(
607 const ShaderCacheCallback& callback) OVERRIDE;
[email protected]840a7e462013-02-27 01:29:51608 virtual void SetWaitSyncPointCallback(
609 const WaitSyncPointCallback& callback) OVERRIDE;
[email protected]22f320a2011-08-30 01:17:00610
[email protected]85a4ac22013-05-31 01:58:47611 virtual AsyncPixelTransferManager*
612 GetAsyncPixelTransferManager() OVERRIDE;
613 virtual void ResetAsyncPixelTransferManagerForTest() OVERRIDE;
[email protected]498b5c072013-06-04 19:30:07614 virtual void SetAsyncPixelTransferManagerForTest(
615 AsyncPixelTransferManager* manager) OVERRIDE;
[email protected]69a8701e2013-03-07 21:31:09616 void ProcessFinishedAsyncTransfers();
[email protected]32145a92012-12-17 09:01:59617
[email protected]1318e922010-09-17 22:03:16618 virtual bool GetServiceTextureId(uint32 client_texture_id,
[email protected]b8e97b62012-09-30 15:09:00619 uint32* service_texture_id) OVERRIDE;
[email protected]43f28f832010-02-03 02:28:48620
[email protected]63b465922012-09-06 02:04:52621 virtual uint32 GetTextureUploadCount() OVERRIDE;
622 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
623 virtual base::TimeDelta GetTotalProcessingCommandsTime() OVERRIDE;
[email protected]dc25dda2012-09-27 21:36:30624 virtual void AddProcessingCommandsTime(base::TimeDelta) OVERRIDE;
[email protected]63b465922012-09-06 02:04:52625
[email protected]8e3e0662010-08-23 18:46:30626 // Restores the current state to the user's settings.
627 void RestoreCurrentFramebufferBindings();
[email protected]8e3e0662010-08-23 18:46:30628
[email protected]297ca1c2011-06-20 23:08:46629 // Sets DEPTH_TEST, STENCIL_TEST and color mask for the current framebuffer.
630 void ApplyDirtyState();
631
632 // These check the state of the currently bound framebuffer or the
633 // backbuffer if no framebuffer is bound.
[email protected]f3b191b2013-06-19 03:43:54634 // If all_draw_buffers is false, only check with COLOR_ATTACHMENT0, otherwise
635 // check with all attached and enabled color attachments.
636 bool BoundFramebufferHasColorAttachmentWithAlpha(bool all_draw_buffers);
[email protected]297ca1c2011-06-20 23:08:46637 bool BoundFramebufferHasDepthAttachment();
638 bool BoundFramebufferHasStencilAttachment();
639
[email protected]b8e97b62012-09-30 15:09:00640 virtual error::ContextLostReason GetContextLostReason() OVERRIDE;
[email protected]38d139d2011-07-14 00:38:43641
[email protected]91c94eb2013-10-22 10:32:54642 // Overridden from FramebufferManager::TextureDetachObserver:
643 virtual void OnTextureRefDetachedFromFramebuffer(
644 TextureRef* texture) OVERRIDE;
645
[email protected]f42f05b2013-11-15 21:46:18646 // Helpers to facilitate calling into compatible extensions.
647 static void RenderbufferStorageMultisampleHelper(
648 const FeatureInfo* feature_info,
649 GLenum target,
650 GLsizei samples,
651 GLenum internal_format,
652 GLsizei width,
653 GLsizei height);
654
655 void BlitFramebufferHelper(GLint srcX0,
656 GLint srcY0,
657 GLint srcX1,
658 GLint srcY1,
659 GLint dstX0,
660 GLint dstY0,
661 GLint dstX1,
662 GLint dstY1,
663 GLbitfield mask,
664 GLenum filter);
[email protected]345ba902013-11-14 21:39:00665
[email protected]96449d2c2009-11-25 00:01:32666 private:
[email protected]70d34263c2013-01-09 00:27:45667 friend class ScopedFrameBufferBinder;
[email protected]34ff8b0c2010-10-01 20:06:02668 friend class ScopedResolvedFrameBufferBinder;
[email protected]ed9f9cd2013-02-27 21:12:35669 friend class BackFramebuffer;
[email protected]6217d392010-03-25 22:08:35670
[email protected]c2f8c8402010-12-06 18:07:24671 // Initialize or re-initialize the shader translator.
672 bool InitializeShaderTranslator();
673
[email protected]302ce6d2011-07-07 23:28:11674 void UpdateCapabilities();
675
[email protected]ae51d192010-04-27 00:48:03676 // Helpers for the glGen and glDelete functions.
677 bool GenTexturesHelper(GLsizei n, const GLuint* client_ids);
678 void DeleteTexturesHelper(GLsizei n, const GLuint* client_ids);
679 bool GenBuffersHelper(GLsizei n, const GLuint* client_ids);
680 void DeleteBuffersHelper(GLsizei n, const GLuint* client_ids);
681 bool GenFramebuffersHelper(GLsizei n, const GLuint* client_ids);
682 void DeleteFramebuffersHelper(GLsizei n, const GLuint* client_ids);
683 bool GenRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
684 void DeleteRenderbuffersHelper(GLsizei n, const GLuint* client_ids);
[email protected]882ba1e22012-03-08 19:02:53685 bool GenQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
686 void DeleteQueriesEXTHelper(GLsizei n, const GLuint* client_ids);
[email protected]944b62f32012-09-27 02:20:46687 bool GenVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
688 void DeleteVertexArraysOESHelper(GLsizei n, const GLuint* client_ids);
[email protected]a93bb842010-02-16 23:03:47689
[email protected]70d34263c2013-01-09 00:27:45690 // Workarounds
691 void OnFboChanged() const;
[email protected]28718a92013-04-04 12:12:51692 void OnUseFramebuffer() const;
[email protected]70d34263c2013-01-09 00:27:45693
[email protected]3916c97e2010-02-25 03:20:50694 // TODO(gman): Cache these pointers?
[email protected]3916c97e2010-02-25 03:20:50695 BufferManager* buffer_manager() {
696 return group_->buffer_manager();
697 }
698
[email protected]a25fa872010-03-25 02:57:58699 RenderbufferManager* renderbuffer_manager() {
700 return group_->renderbuffer_manager();
701 }
702
703 FramebufferManager* framebuffer_manager() {
704 return group_->framebuffer_manager();
705 }
706
[email protected]3916c97e2010-02-25 03:20:50707 ProgramManager* program_manager() {
708 return group_->program_manager();
709 }
710
711 ShaderManager* shader_manager() {
712 return group_->shader_manager();
713 }
714
[email protected]29a4d902013-02-26 20:18:06715 const TextureManager* texture_manager() const {
716 return group_->texture_manager();
717 }
718
[email protected]3916c97e2010-02-25 03:20:50719 TextureManager* texture_manager() {
720 return group_->texture_manager();
721 }
722
[email protected]78b514b2012-05-01 21:50:59723 MailboxManager* mailbox_manager() {
724 return group_->mailbox_manager();
725 }
726
[email protected]09d50362012-10-18 20:54:37727 ImageManager* image_manager() {
728 return group_->image_manager();
729 }
730
[email protected]944b62f32012-09-27 02:20:46731 VertexArrayManager* vertex_array_manager() {
732 return vertex_array_manager_.get();
733 }
734
[email protected]7989c9e2013-01-23 06:39:26735 MemoryTracker* memory_tracker() {
736 return group_->memory_tracker();
737 }
738
[email protected]4f9958142013-07-02 03:58:07739 StreamTextureManager* stream_texture_manager() const {
740 return group_->stream_texture_manager();
741 }
742
[email protected]7989c9e2013-01-23 06:39:26743 bool EnsureGPUMemoryAvailable(size_t estimated_size) {
744 MemoryTracker* tracker = memory_tracker();
745 if (tracker) {
746 return tracker->EnsureGPUMemoryAvailable(estimated_size);
747 }
748 return true;
749 }
750
[email protected]34ff8b0c2010-10-01 20:06:02751 bool IsOffscreenBufferMultisampled() const {
752 return offscreen_target_samples_ > 1;
753 }
754
[email protected]ed9f9cd2013-02-27 21:12:35755 // Creates a Texture for the given texture.
[email protected]370eaf12013-05-18 09:19:49756 TextureRef* CreateTexture(
[email protected]ae51d192010-04-27 00:48:03757 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35758 return texture_manager()->CreateTexture(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47759 }
760
761 // Gets the texture info for the given texture. Returns NULL if none exists.
[email protected]370eaf12013-05-18 09:19:49762 TextureRef* GetTexture(GLuint client_id) const {
[email protected]02965c22013-03-09 02:40:07763 return texture_manager()->GetTexture(client_id);
[email protected]a93bb842010-02-16 23:03:47764 }
765
766 // Deletes the texture info for the given texture.
[email protected]ed9f9cd2013-02-27 21:12:35767 void RemoveTexture(GLuint client_id) {
768 texture_manager()->RemoveTexture(client_id);
[email protected]3916c97e2010-02-25 03:20:50769 }
[email protected]a93bb842010-02-16 23:03:47770
[email protected]d37231fa2010-04-09 21:16:02771 // Get the size (in pixels) of the currently bound frame buffer (either FBO
772 // or regular back buffer).
[email protected]8e3e0662010-08-23 18:46:30773 gfx::Size GetBoundReadFrameBufferSize();
[email protected]d37231fa2010-04-09 21:16:02774
[email protected]9edc6b22010-12-23 02:00:26775 // Get the format of the currently bound frame buffer (either FBO or regular
776 // back buffer)
[email protected]68586372013-12-11 01:27:59777 GLenum GetBoundReadFrameBufferTextureType();
[email protected]9edc6b22010-12-23 02:00:26778 GLenum GetBoundReadFrameBufferInternalFormat();
[email protected]297ca1c2011-06-20 23:08:46779 GLenum GetBoundDrawFrameBufferInternalFormat();
[email protected]9edc6b22010-12-23 02:00:26780
[email protected]a93bb842010-02-16 23:03:47781 // Wrapper for CompressedTexImage2D commands.
782 error::Error DoCompressedTexImage2D(
[email protected]09d50362012-10-18 20:54:37783 GLenum target,
784 GLint level,
785 GLenum internal_format,
786 GLsizei width,
787 GLsizei height,
788 GLint border,
789 GLsizei image_size,
790 const void* data);
[email protected]a93bb842010-02-16 23:03:47791
[email protected]cadde4a2010-07-31 17:10:43792 // Wrapper for CompressedTexSubImage2D.
793 void DoCompressedTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37794 GLenum target,
795 GLint level,
796 GLint xoffset,
797 GLint yoffset,
798 GLsizei width,
799 GLsizei height,
800 GLenum format,
801 GLsizei imageSize,
802 const void * data);
[email protected]cadde4a2010-07-31 17:10:43803
804 // Wrapper for CopyTexImage2D.
805 void DoCopyTexImage2D(
[email protected]09d50362012-10-18 20:54:37806 GLenum target,
807 GLint level,
808 GLenum internal_format,
809 GLint x,
810 GLint y,
811 GLsizei width,
812 GLsizei height,
813 GLint border);
[email protected]cadde4a2010-07-31 17:10:43814
[email protected]6d792ee12013-05-15 00:40:56815 // Wrapper for SwapBuffers.
816 void DoSwapBuffers();
817
[email protected]cadde4a2010-07-31 17:10:43818 // Wrapper for CopyTexSubImage2D.
819 void DoCopyTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37820 GLenum target,
821 GLint level,
822 GLint xoffset,
823 GLint yoffset,
824 GLint x,
825 GLint y,
826 GLsizei width,
827 GLsizei height);
[email protected]cadde4a2010-07-31 17:10:43828
[email protected]f598f422012-12-07 08:30:03829 // Validation for TexSubImage2D.
830 bool ValidateTexSubImage2D(
831 error::Error* error,
832 const char* function_name,
833 GLenum target,
834 GLint level,
835 GLint xoffset,
836 GLint yoffset,
837 GLsizei width,
838 GLsizei height,
839 GLenum format,
840 GLenum type,
841 const void * data);
842
[email protected]cadde4a2010-07-31 17:10:43843 // Wrapper for TexSubImage2D.
[email protected]f598f422012-12-07 08:30:03844 error::Error DoTexSubImage2D(
[email protected]09d50362012-10-18 20:54:37845 GLenum target,
846 GLint level,
847 GLint xoffset,
848 GLint yoffset,
849 GLsizei width,
850 GLsizei height,
851 GLenum format,
852 GLenum type,
853 const void * data);
[email protected]cadde4a2010-07-31 17:10:43854
[email protected]32145a92012-12-17 09:01:59855 // Extra validation for async tex(Sub)Image2D.
856 bool ValidateAsyncTransfer(
857 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:47858 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:59859 GLenum target,
860 GLint level,
861 const void * data);
862
[email protected]e51bdf32011-11-23 22:21:46863 // Wrapper for TexImageIOSurface2DCHROMIUM.
864 void DoTexImageIOSurface2DCHROMIUM(
[email protected]09d50362012-10-18 20:54:37865 GLenum target,
866 GLsizei width,
867 GLsizei height,
868 GLuint io_surface_id,
869 GLuint plane);
[email protected]e51bdf32011-11-23 22:21:46870
[email protected]43410e92012-04-20 17:06:28871 void DoCopyTextureCHROMIUM(
[email protected]09d50362012-10-18 20:54:37872 GLenum target,
873 GLuint source_id,
874 GLuint target_id,
875 GLint level,
[email protected]a4a6bdd12013-04-19 20:46:54876 GLenum internal_format,
877 GLenum dest_type);
[email protected]43410e92012-04-20 17:06:28878
[email protected]97dc7cbe2011-12-06 17:26:17879 // Wrapper for TexStorage2DEXT.
880 void DoTexStorage2DEXT(
[email protected]09d50362012-10-18 20:54:37881 GLenum target,
882 GLint levels,
883 GLenum internal_format,
884 GLsizei width,
885 GLsizei height);
[email protected]97dc7cbe2011-12-06 17:26:17886
[email protected]78b514b2012-05-01 21:50:59887 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
888 void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
889
[email protected]09d50362012-10-18 20:54:37890 void DoBindTexImage2DCHROMIUM(
891 GLenum target,
892 GLint image_id);
893 void DoReleaseTexImage2DCHROMIUM(
894 GLenum target,
895 GLint image_id);
896
[email protected]94307712012-11-16 23:26:11897 void DoTraceEndCHROMIUM(void);
898
[email protected]2f143d482013-03-14 18:04:49899 void DoDrawBuffersEXT(GLsizei count, const GLenum* bufs);
900
[email protected]ed9f9cd2013-02-27 21:12:35901 // Creates a Program for the given program.
902 Program* CreateProgram(
[email protected]d685a682011-04-29 16:19:57903 GLuint client_id, GLuint service_id) {
[email protected]ed9f9cd2013-02-27 21:12:35904 return program_manager()->CreateProgram(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47905 }
906
[email protected]07f54fcc2009-12-22 02:46:30907 // Gets the program info for the given program. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35908 Program* GetProgram(GLuint client_id) {
909 return program_manager()->GetProgram(client_id);
[email protected]1d32bc82010-01-13 22:06:46910 }
[email protected]07f54fcc2009-12-22 02:46:30911
[email protected]cae20172012-12-07 00:06:19912#if defined(NDEBUG)
913 void LogClientServiceMapping(
914 const char* /* function_name */,
915 GLuint /* client_id */,
916 GLuint /* service_id */) {
917 }
918 template<typename T>
919 void LogClientServiceForInfo(
920 T* /* info */, GLuint /* client_id */, const char* /* function_name */) {
921 }
922#else
923 void LogClientServiceMapping(
924 const char* function_name, GLuint client_id, GLuint service_id) {
[email protected]2a22fe72012-12-07 04:21:26925 if (service_logging_) {
[email protected]65f7efe2013-11-28 03:11:47926 VLOG(1) << "[" << logger_.GetLogPrefix() << "] " << function_name
927 << ": client_id = " << client_id
928 << ", service_id = " << service_id;
[email protected]2a22fe72012-12-07 04:21:26929 }
[email protected]cae20172012-12-07 00:06:19930 }
931 template<typename T>
932 void LogClientServiceForInfo(
933 T* info, GLuint client_id, const char* function_name) {
[email protected]2a22fe72012-12-07 04:21:26934 if (info) {
[email protected]cae20172012-12-07 00:06:19935 LogClientServiceMapping(function_name, client_id, info->service_id());
936 }
937 }
938#endif
939
[email protected]6b8cf1a2010-05-06 16:13:58940 // Gets the program info for the given program. If it's not a program
941 // generates a GL error. Returns NULL if not program.
[email protected]ed9f9cd2013-02-27 21:12:35942 Program* GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:58943 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42944 Program* program = GetProgram(client_id);
945 if (!program) {
[email protected]ed9f9cd2013-02-27 21:12:35946 if (GetShader(client_id)) {
[email protected]ab09b612013-03-11 22:11:51947 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43948 GL_INVALID_OPERATION, function_name, "shader passed for program");
[email protected]6b8cf1a2010-05-06 16:13:58949 } else {
[email protected]ab09b612013-03-11 22:11:51950 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "unknown program");
[email protected]6b8cf1a2010-05-06 16:13:58951 }
952 }
[email protected]df37b9932013-03-08 05:21:42953 LogClientServiceForInfo(program, client_id, function_name);
954 return program;
[email protected]6b8cf1a2010-05-06 16:13:58955 }
956
957
[email protected]ed9f9cd2013-02-27 21:12:35958 // Creates a Shader for the given shader.
959 Shader* CreateShader(
[email protected]d685a682011-04-29 16:19:57960 GLuint client_id,
961 GLuint service_id,
962 GLenum shader_type) {
[email protected]ed9f9cd2013-02-27 21:12:35963 return shader_manager()->CreateShader(
[email protected]d685a682011-04-29 16:19:57964 client_id, service_id, shader_type);
[email protected]45bf5152010-02-12 00:11:31965 }
966
967 // Gets the shader info for the given shader. Returns NULL if none exists.
[email protected]ed9f9cd2013-02-27 21:12:35968 Shader* GetShader(GLuint client_id) {
969 return shader_manager()->GetShader(client_id);
[email protected]45bf5152010-02-12 00:11:31970 }
971
[email protected]6b8cf1a2010-05-06 16:13:58972 // Gets the shader info for the given shader. If it's not a shader generates a
973 // GL error. Returns NULL if not shader.
[email protected]ed9f9cd2013-02-27 21:12:35974 Shader* GetShaderInfoNotProgram(
[email protected]6b8cf1a2010-05-06 16:13:58975 GLuint client_id, const char* function_name) {
[email protected]df37b9932013-03-08 05:21:42976 Shader* shader = GetShader(client_id);
977 if (!shader) {
[email protected]ed9f9cd2013-02-27 21:12:35978 if (GetProgram(client_id)) {
[email protected]ab09b612013-03-11 22:11:51979 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43980 GL_INVALID_OPERATION, function_name, "program passed for shader");
[email protected]6b8cf1a2010-05-06 16:13:58981 } else {
[email protected]ab09b612013-03-11 22:11:51982 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:43983 GL_INVALID_VALUE, function_name, "unknown shader");
[email protected]6b8cf1a2010-05-06 16:13:58984 }
985 }
[email protected]df37b9932013-03-08 05:21:42986 LogClientServiceForInfo(shader, client_id, function_name);
987 return shader;
[email protected]6b8cf1a2010-05-06 16:13:58988 }
989
[email protected]a93bb842010-02-16 23:03:47990 // Creates a buffer info for the given buffer.
[email protected]ed9f9cd2013-02-27 21:12:35991 void CreateBuffer(GLuint client_id, GLuint service_id) {
992 return buffer_manager()->CreateBuffer(client_id, service_id);
[email protected]a93bb842010-02-16 23:03:47993 }
994
[email protected]07f54fcc2009-12-22 02:46:30995 // Gets the buffer info for the given buffer.
[email protected]16ccec12013-02-28 03:40:21996 Buffer* GetBuffer(GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:07997 Buffer* buffer = buffer_manager()->GetBuffer(client_id);
998 return buffer;
[email protected]1d32bc82010-01-13 22:06:46999 }
[email protected]07f54fcc2009-12-22 02:46:301000
[email protected]a93bb842010-02-16 23:03:471001 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
1002 // on glDeleteBuffers so we can make sure the user does not try to render
1003 // with deleted buffers.
[email protected]ed9f9cd2013-02-27 21:12:351004 void RemoveBuffer(GLuint client_id);
[email protected]a93bb842010-02-16 23:03:471005
[email protected]a25fa872010-03-25 02:57:581006 // Creates a framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351007 void CreateFramebuffer(GLuint client_id, GLuint service_id) {
1008 return framebuffer_manager()->CreateFramebuffer(client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581009 }
1010
1011 // Gets the framebuffer info for the given framebuffer.
[email protected]4d8f0dd2013-03-09 14:37:061012 Framebuffer* GetFramebuffer(GLuint client_id) {
1013 return framebuffer_manager()->GetFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581014 }
1015
1016 // Removes the framebuffer info for the given framebuffer.
[email protected]ed9f9cd2013-02-27 21:12:351017 void RemoveFramebuffer(GLuint client_id) {
1018 framebuffer_manager()->RemoveFramebuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581019 }
1020
1021 // Creates a renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351022 void CreateRenderbuffer(GLuint client_id, GLuint service_id) {
1023 return renderbuffer_manager()->CreateRenderbuffer(
[email protected]ae51d192010-04-27 00:48:031024 client_id, service_id);
[email protected]a25fa872010-03-25 02:57:581025 }
1026
1027 // Gets the renderbuffer info for the given renderbuffer.
[email protected]ee2a79c32013-03-10 03:50:271028 Renderbuffer* GetRenderbuffer(GLuint client_id) {
1029 return renderbuffer_manager()->GetRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581030 }
1031
1032 // Removes the renderbuffer info for the given renderbuffer.
[email protected]ed9f9cd2013-02-27 21:12:351033 void RemoveRenderbuffer(GLuint client_id) {
1034 renderbuffer_manager()->RemoveRenderbuffer(client_id);
[email protected]a25fa872010-03-25 02:57:581035 }
1036
[email protected]944b62f32012-09-27 02:20:461037 // Gets the vertex attrib manager for the given vertex array.
1038 VertexAttribManager* GetVertexAttribManager(GLuint client_id) {
1039 VertexAttribManager* info =
1040 vertex_array_manager()->GetVertexAttribManager(client_id);
1041 return info;
1042 }
1043
1044 // Removes the vertex attrib manager for the given vertex array.
1045 void RemoveVertexAttribManager(GLuint client_id) {
1046 vertex_array_manager()->RemoveVertexAttribManager(client_id);
1047 }
1048
1049 // Creates a vertex attrib manager for the given vertex array.
1050 void CreateVertexAttribManager(GLuint client_id, GLuint service_id) {
1051 return vertex_array_manager()->CreateVertexAttribManager(
1052 client_id, service_id, group_->max_vertex_attribs());
1053 }
1054
[email protected]258a3313f2011-10-18 20:13:571055 void DoBindAttribLocation(GLuint client_id, GLuint index, const char* name);
[email protected]2be6abf32012-06-26 00:28:331056 void DoBindUniformLocationCHROMIUM(
1057 GLuint client_id, GLint location, const char* name);
[email protected]258a3313f2011-10-18 20:13:571058
[email protected]558847a2010-03-24 07:02:541059 error::Error GetAttribLocationHelper(
1060 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1061 const std::string& name_str);
1062
1063 error::Error GetUniformLocationHelper(
1064 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
1065 const std::string& name_str);
1066
[email protected]3916c97e2010-02-25 03:20:501067 // Helper for glShaderSource.
1068 error::Error ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:031069 GLuint client_id, const char* data, uint32 data_size);
[email protected]07f54fcc2009-12-22 02:46:301070
[email protected]0d6bfdc2011-11-02 01:32:201071 // Clear any textures used by the current program.
1072 bool ClearUnclearedTextures();
1073
1074 // Clear any uncleared level in texture.
1075 // Returns false if there was a generated GL error.
[email protected]02965c22013-03-09 02:40:071076 bool ClearTexture(Texture* texture);
[email protected]0d6bfdc2011-11-02 01:32:201077
1078 // Clears any uncleared attachments attached to the given frame buffer.
1079 // Returns false if there was a generated GL error.
[email protected]4d8f0dd2013-03-09 14:37:061080 void ClearUnclearedAttachments(GLenum target, Framebuffer* framebuffer);
[email protected]3a2e7c7b2010-08-06 01:12:281081
[email protected]0d6bfdc2011-11-02 01:32:201082 // overridden from GLES2Decoder
[email protected]b8e97b62012-09-30 15:09:001083 virtual bool ClearLevel(unsigned service_id,
1084 unsigned bind_target,
1085 unsigned target,
1086 int level,
1087 unsigned format,
1088 unsigned type,
1089 int width,
1090 int height,
1091 bool is_texture_immutable) OVERRIDE;
[email protected]0d6bfdc2011-11-02 01:32:201092
[email protected]c007aa02010-09-02 22:22:401093 // Restore all GL state that affects clearing.
1094 void RestoreClearState();
1095
[email protected]3a2e7c7b2010-08-06 01:12:281096 // Remembers the state of some capabilities.
[email protected]297ca1c2011-06-20 23:08:461097 // Returns: true if glEnable/glDisable should actually be called.
1098 bool SetCapabilityState(GLenum cap, bool enabled);
[email protected]3a2e7c7b2010-08-06 01:12:281099
[email protected]0d6bfdc2011-11-02 01:32:201100 // Check that the currently bound framebuffers are valid.
1101 // Generates GL error if not.
1102 bool CheckBoundFramebuffersValid(const char* func_name);
1103
1104 // Check if a framebuffer meets our requirements.
1105 bool CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:351106 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:201107 GLenum target,
1108 const char* func_name);
[email protected]3a03a8f2011-03-19 00:51:271109
[email protected]939e7362010-05-13 20:49:101110 // Checks if the current program exists and is valid. If not generates the
1111 // appropriate GL error. Returns true if the current program is in a usable
1112 // state.
1113 bool CheckCurrentProgram(const char* function_name);
1114
1115 // Checks if the current program exists and is valid and that location is not
1116 // -1. If the current program is not valid generates the appropriate GL
1117 // error. Returns true if the current program is in a usable state and
1118 // location is not -1.
1119 bool CheckCurrentProgramForUniform(GLint location, const char* function_name);
1120
1121 // Gets the type of a uniform for a location in the current program. Sets GL
1122 // errors if the current program is not valid. Returns true if the current
[email protected]43c2f1f2011-03-25 18:35:361123 // program is valid and the location exists. Adjusts count so it
1124 // does not overflow the uniform.
1125 bool PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:121126 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:521127 const BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:121128 GLint* real_location, GLenum* type, GLsizei* count);
[email protected]939e7362010-05-13 20:49:101129
[email protected]b177ae22011-11-01 03:29:111130 // Gets the service id for any simulated backbuffer fbo.
[email protected]1868a342012-11-07 15:56:021131 GLuint GetBackbufferServiceId() const;
[email protected]b177ae22011-11-01 03:29:111132
[email protected]b273e432010-04-12 17:23:581133 // Helper for glGetBooleanv, glGetFloatv and glGetIntegerv
1134 bool GetHelper(GLenum pname, GLint* params, GLsizei* num_written);
1135
[email protected]ac77603c72013-03-08 13:52:061136 // Helper for glGetVertexAttrib
1137 void GetVertexAttribHelper(
1138 const VertexAttrib* attrib, GLenum pname, GLint* param);
1139
[email protected]96449d2c2009-11-25 00:01:321140 // Wrapper for glCreateProgram
[email protected]ae51d192010-04-27 00:48:031141 bool CreateProgramHelper(GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321142
1143 // Wrapper for glCreateShader
[email protected]ae51d192010-04-27 00:48:031144 bool CreateShaderHelper(GLenum type, GLuint client_id);
[email protected]96449d2c2009-11-25 00:01:321145
[email protected]3916c97e2010-02-25 03:20:501146 // Wrapper for glActiveTexture
1147 void DoActiveTexture(GLenum texture_unit);
1148
[email protected]ae51d192010-04-27 00:48:031149 // Wrapper for glAttachShader
1150 void DoAttachShader(GLuint client_program_id, GLint client_shader_id);
1151
[email protected]96449d2c2009-11-25 00:01:321152 // Wrapper for glBindBuffer since we need to track the current targets.
1153 void DoBindBuffer(GLenum target, GLuint buffer);
1154
[email protected]86093972010-03-11 00:13:561155 // Wrapper for glBindFramebuffer since we need to track the current targets.
1156 void DoBindFramebuffer(GLenum target, GLuint framebuffer);
1157
1158 // Wrapper for glBindRenderbuffer since we need to track the current targets.
1159 void DoBindRenderbuffer(GLenum target, GLuint renderbuffer);
1160
[email protected]a93bb842010-02-16 23:03:471161 // Wrapper for glBindTexture since we need to track the current targets.
1162 void DoBindTexture(GLenum target, GLuint texture);
1163
[email protected]944b62f32012-09-27 02:20:461164 // Wrapper for glBindVertexArrayOES
1165 void DoBindVertexArrayOES(GLuint array);
[email protected]ab4fd7282012-10-12 16:25:571166 void EmulateVertexArrayState();
[email protected]944b62f32012-09-27 02:20:461167
[email protected]49cabed2013-11-13 18:15:181168 // Wrapper for glBlitFramebufferCHROMIUM.
1169 void DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301170 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
1171 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
1172 GLbitfield mask, GLenum filter);
1173
[email protected]36cef8ce2010-03-16 07:34:451174 // Wrapper for glBufferSubData.
[email protected]0c86dbf2010-03-05 08:14:111175 void DoBufferSubData(
1176 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data);
1177
[email protected]36cef8ce2010-03-16 07:34:451178 // Wrapper for glCheckFramebufferStatus
1179 GLenum DoCheckFramebufferStatus(GLenum target);
1180
[email protected]3a03a8f2011-03-19 00:51:271181 // Wrapper for glClear
[email protected]a7266a92012-06-28 02:11:081182 error::Error DoClear(GLbitfield mask);
[email protected]3a03a8f2011-03-19 00:51:271183
[email protected]88a61bf2012-10-27 13:00:421184 // Wrappers for various state.
[email protected]88a61bf2012-10-27 13:00:421185 void DoDepthRangef(GLclampf znear, GLclampf zfar);
[email protected]b04e24c2013-01-08 18:35:251186 void DoSampleCoverage(GLclampf value, GLboolean invert);
[email protected]3a2e7c7b2010-08-06 01:12:281187
[email protected]45bf5152010-02-12 00:11:311188 // Wrapper for glCompileShader.
1189 void DoCompileShader(GLuint shader);
1190
[email protected]269200b12010-11-18 22:53:061191 // Helper for DeleteSharedIdsCHROMIUM commands.
1192 void DoDeleteSharedIdsCHROMIUM(
1193 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101194
[email protected]ae51d192010-04-27 00:48:031195 // Wrapper for glDetachShader
1196 void DoDetachShader(GLuint client_program_id, GLint client_shader_id);
1197
[email protected]3a2e7c7b2010-08-06 01:12:281198 // Wrapper for glDisable
1199 void DoDisable(GLenum cap);
1200
[email protected]07f54fcc2009-12-22 02:46:301201 // Wrapper for glDisableVertexAttribArray.
1202 void DoDisableVertexAttribArray(GLuint index);
1203
[email protected]60f22d32012-12-12 00:31:581204 // Wrapper for glDiscardFramebufferEXT, since we need to track undefined
1205 // attachments.
1206 void DoDiscardFramebufferEXT(GLenum target,
1207 GLsizei numAttachments,
1208 const GLenum* attachments);
1209
[email protected]3a2e7c7b2010-08-06 01:12:281210 // Wrapper for glEnable
1211 void DoEnable(GLenum cap);
1212
[email protected]07f54fcc2009-12-22 02:46:301213 // Wrapper for glEnableVertexAttribArray.
1214 void DoEnableVertexAttribArray(GLuint index);
1215
[email protected]882ba1e22012-03-08 19:02:531216 // Wrapper for glFinish.
1217 void DoFinish();
1218
1219 // Wrapper for glFlush.
1220 void DoFlush();
1221
[email protected]36cef8ce2010-03-16 07:34:451222 // Wrapper for glFramebufferRenderbufffer.
1223 void DoFramebufferRenderbuffer(
1224 GLenum target, GLenum attachment, GLenum renderbuffertarget,
1225 GLuint renderbuffer);
1226
1227 // Wrapper for glFramebufferTexture2D.
1228 void DoFramebufferTexture2D(
1229 GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
1230 GLint level);
1231
[email protected]7d3c36e2013-07-12 14:13:161232 // Wrapper for glFramebufferTexture2DMultisampleEXT.
1233 void DoFramebufferTexture2DMultisample(
1234 GLenum target, GLenum attachment, GLenum textarget,
1235 GLuint texture, GLint level, GLsizei samples);
1236
1237 // Common implementation for both DoFramebufferTexture2D wrappers.
1238 void DoFramebufferTexture2DCommon(const char* name,
1239 GLenum target, GLenum attachment, GLenum textarget,
1240 GLuint texture, GLint level, GLsizei samples);
1241
[email protected]a93bb842010-02-16 23:03:471242 // Wrapper for glGenerateMipmap
1243 void DoGenerateMipmap(GLenum target);
1244
[email protected]269200b12010-11-18 22:53:061245 // Helper for GenSharedIdsCHROMIUM commands.
1246 void DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:101247 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
1248
[email protected]7d3c36e2013-07-12 14:13:161249 // Helper for DoGetBooleanv, Floatv, and Intergerv to adjust pname
1250 // to account for different pname values defined in different extension
1251 // variants.
1252 GLenum AdjustGetPname(GLenum pname);
1253
[email protected]b273e432010-04-12 17:23:581254 // Wrapper for DoGetBooleanv.
1255 void DoGetBooleanv(GLenum pname, GLboolean* params);
1256
1257 // Wrapper for DoGetFloatv.
1258 void DoGetFloatv(GLenum pname, GLfloat* params);
1259
[email protected]36cef8ce2010-03-16 07:34:451260 // Wrapper for glGetFramebufferAttachmentParameteriv.
1261 void DoGetFramebufferAttachmentParameteriv(
1262 GLenum target, GLenum attachment, GLenum pname, GLint* params);
1263
[email protected]a0c3e972010-04-21 00:49:131264 // Wrapper for glGetIntegerv.
[email protected]b273e432010-04-12 17:23:581265 void DoGetIntegerv(GLenum pname, GLint* params);
1266
[email protected]29a9eb52010-04-13 09:04:231267 // Gets the max value in a range in a buffer.
[email protected]269200b12010-11-18 22:53:061268 GLuint DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:231269 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
1270
[email protected]17cfbe0e2013-03-07 01:26:081271 // Wrapper for glGetBufferParameteriv.
1272 void DoGetBufferParameteriv(
1273 GLenum target, GLenum pname, GLint* params);
1274
[email protected]a0c3e972010-04-21 00:49:131275 // Wrapper for glGetProgramiv.
1276 void DoGetProgramiv(
1277 GLuint program_id, GLenum pname, GLint* params);
1278
[email protected]36cef8ce2010-03-16 07:34:451279 // Wrapper for glRenderbufferParameteriv.
1280 void DoGetRenderbufferParameteriv(
1281 GLenum target, GLenum pname, GLint* params);
1282
[email protected]ddd968b82010-03-02 00:44:291283 // Wrapper for glGetShaderiv
1284 void DoGetShaderiv(GLuint shader, GLenum pname, GLint* params);
1285
[email protected]b1122982010-05-17 23:04:241286 // Wrappers for glGetVertexAttrib.
1287 void DoGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params);
1288 void DoGetVertexAttribiv(GLuint index, GLenum pname, GLint *params);
1289
[email protected]1958e0e2010-04-22 05:17:151290 // Wrappers for glIsXXX functions.
[email protected]3dc69c42012-05-12 02:29:241291 bool DoIsEnabled(GLenum cap);
[email protected]1958e0e2010-04-22 05:17:151292 bool DoIsBuffer(GLuint client_id);
1293 bool DoIsFramebuffer(GLuint client_id);
1294 bool DoIsProgram(GLuint client_id);
1295 bool DoIsRenderbuffer(GLuint client_id);
1296 bool DoIsShader(GLuint client_id);
1297 bool DoIsTexture(GLuint client_id);
[email protected]944b62f32012-09-27 02:20:461298 bool DoIsVertexArrayOES(GLuint client_id);
[email protected]1958e0e2010-04-22 05:17:151299
[email protected]07f54fcc2009-12-22 02:46:301300 // Wrapper for glLinkProgram
1301 void DoLinkProgram(GLuint program);
1302
[email protected]269200b12010-11-18 22:53:061303 // Helper for RegisterSharedIdsCHROMIUM.
1304 void DoRegisterSharedIdsCHROMIUM(
1305 GLuint namespace_id, GLsizei n, const GLuint* ids);
[email protected]066849e32010-05-03 19:14:101306
[email protected]36cef8ce2010-03-16 07:34:451307 // Wrapper for glRenderbufferStorage.
1308 void DoRenderbufferStorage(
[email protected]ae51d192010-04-27 00:48:031309 GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
[email protected]36cef8ce2010-03-16 07:34:451310
[email protected]49cabed2013-11-13 18:15:181311 // Handler for glRenderbufferStorageMultisampleCHROMIUM.
1312 void DoRenderbufferStorageMultisampleCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:301313 GLenum target, GLsizei samples, GLenum internalformat,
1314 GLsizei width, GLsizei height);
1315
[email protected]49cabed2013-11-13 18:15:181316 // Handler for glRenderbufferStorageMultisampleEXT
1317 // (multisampled_render_to_texture).
1318 void DoRenderbufferStorageMultisampleEXT(
1319 GLenum target, GLsizei samples, GLenum internalformat,
1320 GLsizei width, GLsizei height);
1321
1322 // Common validation for multisample extensions.
1323 bool ValidateRenderbufferStorageMultisample(GLsizei samples,
1324 GLenum internalformat,
1325 GLsizei width,
1326 GLsizei height);
1327
[email protected]4a4c18b2013-09-13 22:50:101328 // Verifies that the currently bound multisample renderbuffer is valid
1329 // Very slow! Only done on platforms with driver bugs that return invalid
1330 // buffers under memory pressure
1331 bool VerifyMultisampleRenderbufferIntegrity(
1332 GLuint renderbuffer, GLenum format);
1333
[email protected]b273e432010-04-12 17:23:581334 // Wrapper for glReleaseShaderCompiler.
1335 void DoReleaseShaderCompiler() { }
1336
[email protected]3916c97e2010-02-25 03:20:501337 // Wrappers for glTexParameter functions.
1338 void DoTexParameterf(GLenum target, GLenum pname, GLfloat param);
1339 void DoTexParameteri(GLenum target, GLenum pname, GLint param);
1340 void DoTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
1341 void DoTexParameteriv(GLenum target, GLenum pname, const GLint* params);
1342
1343 // Wrappers for glUniform1i and glUniform1iv as according to the GLES2
1344 // spec only these 2 functions can be used to set sampler uniforms.
[email protected]1b0a6752012-02-22 03:44:121345 void DoUniform1i(GLint fake_location, GLint v0);
1346 void DoUniform1iv(GLint fake_location, GLsizei count, const GLint* value);
1347 void DoUniform2iv(GLint fake_location, GLsizei count, const GLint* value);
1348 void DoUniform3iv(GLint fake_location, GLsizei count, const GLint* value);
1349 void DoUniform4iv(GLint fake_location, GLsizei count, const GLint* value);
[email protected]939e7362010-05-13 20:49:101350
1351 // Wrappers for glUniformfv because some drivers don't correctly accept
1352 // bool uniforms.
[email protected]1b0a6752012-02-22 03:44:121353 void DoUniform1fv(GLint fake_location, GLsizei count, const GLfloat* value);
1354 void DoUniform2fv(GLint fake_location, GLsizei count, const GLfloat* value);
1355 void DoUniform3fv(GLint fake_location, GLsizei count, const GLfloat* value);
1356 void DoUniform4fv(GLint fake_location, GLsizei count, const GLfloat* value);
[email protected]3916c97e2010-02-25 03:20:501357
[email protected]43c2f1f2011-03-25 18:35:361358 void DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:121359 GLint fake_location, GLsizei count, GLboolean transpose,
1360 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361361 void DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:121362 GLint fake_location, GLsizei count, GLboolean transpose,
1363 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361364 void DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:121365 GLint fake_location, GLsizei count, GLboolean transpose,
1366 const GLfloat* value);
[email protected]43c2f1f2011-03-25 18:35:361367
[email protected]af6380962012-11-29 23:24:131368 bool SetVertexAttribValue(
1369 const char* function_name, GLuint index, const GLfloat* value);
1370
[email protected]b1122982010-05-17 23:04:241371 // Wrappers for glVertexAttrib??
1372 void DoVertexAttrib1f(GLuint index, GLfloat v0);
1373 void DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1);
1374 void DoVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
1375 void DoVertexAttrib4f(
1376 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
1377 void DoVertexAttrib1fv(GLuint index, const GLfloat *v);
1378 void DoVertexAttrib2fv(GLuint index, const GLfloat *v);
1379 void DoVertexAttrib3fv(GLuint index, const GLfloat *v);
1380 void DoVertexAttrib4fv(GLuint index, const GLfloat *v);
1381
[email protected]43410e92012-04-20 17:06:281382 // Wrapper for glViewport
1383 void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height);
1384
[email protected]07f54fcc2009-12-22 02:46:301385 // Wrapper for glUseProgram
1386 void DoUseProgram(GLuint program);
1387
[email protected]ae51d192010-04-27 00:48:031388 // Wrapper for glValidateProgram.
1389 void DoValidateProgram(GLuint program_client_id);
1390
[email protected]d2a0e1a2012-08-12 02:25:011391 void DoInsertEventMarkerEXT(GLsizei length, const GLchar* marker);
1392 void DoPushGroupMarkerEXT(GLsizei length, const GLchar* group);
1393 void DoPopGroupMarkerEXT(void);
1394
[email protected]4e8a5b122010-05-08 22:00:101395 // Gets the number of values that will be returned by glGetXXX. Returns
1396 // false if pname is unknown.
1397 bool GetNumValuesReturnedForGLGet(GLenum pname, GLsizei* num_values);
1398
[email protected]07f54fcc2009-12-22 02:46:301399 // Checks if the current program and vertex attributes are valid for drawing.
[email protected]ad84a3a2012-06-08 21:42:431400 bool IsDrawValid(
1401 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount);
[email protected]07f54fcc2009-12-22 02:46:301402
[email protected]c13e1da62011-09-09 21:48:301403 // Returns true if successful, simulated will be true if attrib0 was
1404 // simulated.
[email protected]c6aef902012-02-14 03:31:421405 bool SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:431406 const char* function_name, GLuint max_vertex_accessed, bool* simulated);
[email protected]43410e92012-04-20 17:06:281407 void RestoreStateForAttrib(GLuint attrib);
[email protected]b1122982010-05-17 23:04:241408
[email protected]e56131d22013-07-28 16:14:111409 // If texture is a stream texture, this will update the stream to the newest
[email protected]e8dc5662013-10-17 23:28:291410 // buffer and bind the texture implicitly.
1411 void UpdateStreamTextureIfNeeded(Texture* texture, GLuint texture_unit_index);
[email protected]e56131d22013-07-28 16:14:111412
[email protected]91c94eb2013-10-22 10:32:541413 // If an image is bound to texture, this will call Will/DidUseTexImage
1414 // if needed.
1415 void DoWillUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1416 void DoDidUseTexImageIfNeeded(Texture* texture, GLenum textarget);
1417
1418 // Returns false if textures were replaced.
[email protected]e56131d22013-07-28 16:14:111419 bool PrepareTexturesForRender();
[email protected]91c94eb2013-10-22 10:32:541420 void RestoreStateForTextures();
[email protected]3916c97e2010-02-25 03:20:501421
[email protected]8fbedc02010-11-18 18:43:401422 // Returns true if GL_FIXED attribs were simulated.
[email protected]c6aef902012-02-14 03:31:421423 bool SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:431424 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421425 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount);
[email protected]8fbedc02010-11-18 18:43:401426 void RestoreStateForSimulatedFixedAttribs();
1427
[email protected]c6aef902012-02-14 03:31:421428 // Handle DrawArrays and DrawElements for both instanced and non-instanced
1429 // cases (primcount is 0 for non-instanced).
1430 error::Error DoDrawArrays(
[email protected]ad84a3a2012-06-08 21:42:431431 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421432 bool instanced, GLenum mode, GLint first, GLsizei count,
1433 GLsizei primcount);
1434 error::Error DoDrawElements(
[email protected]ad84a3a2012-06-08 21:42:431435 const char* function_name,
[email protected]c6aef902012-02-14 03:31:421436 bool instanced, GLenum mode, GLsizei count, GLenum type,
1437 int32 offset, GLsizei primcount);
1438
[email protected]61eeb33f2011-07-26 15:30:311439 GLenum GetBindTargetForSamplerType(GLenum type) {
1440 DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
[email protected]e51bdf32011-11-23 22:21:461441 type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
1442 switch (type) {
1443 case GL_SAMPLER_2D:
1444 return GL_TEXTURE_2D;
1445 case GL_SAMPLER_CUBE:
1446 return GL_TEXTURE_CUBE_MAP;
1447 case GL_SAMPLER_EXTERNAL_OES:
1448 return GL_TEXTURE_EXTERNAL_OES;
1449 case GL_SAMPLER_2D_RECT_ARB:
1450 return GL_TEXTURE_RECTANGLE_ARB;
1451 }
1452
1453 NOTREACHED();
1454 return 0;
[email protected]61eeb33f2011-07-26 15:30:311455 }
1456
[email protected]8e3e0662010-08-23 18:46:301457 // Gets the framebuffer info for a particular target.
[email protected]4d8f0dd2013-03-09 14:37:061458 Framebuffer* GetFramebufferInfoForTarget(GLenum target) {
1459 Framebuffer* framebuffer = NULL;
[email protected]8e3e0662010-08-23 18:46:301460 switch (target) {
1461 case GL_FRAMEBUFFER:
[email protected]ebfb73c2012-08-15 02:37:451462 case GL_DRAW_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341463 framebuffer = framebuffer_state_.bound_draw_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301464 break;
[email protected]ebfb73c2012-08-15 02:37:451465 case GL_READ_FRAMEBUFFER_EXT:
[email protected]9d3b2e12013-10-02 01:04:341466 framebuffer = framebuffer_state_.bound_read_framebuffer.get();
[email protected]8e3e0662010-08-23 18:46:301467 break;
1468 default:
1469 NOTREACHED();
1470 break;
1471 }
[email protected]4d8f0dd2013-03-09 14:37:061472 return framebuffer;
[email protected]8e3e0662010-08-23 18:46:301473 }
1474
[email protected]ed9f9cd2013-02-27 21:12:351475 Renderbuffer* GetRenderbufferInfoForTarget(
[email protected]0d6bfdc2011-11-02 01:32:201476 GLenum target) {
[email protected]ee2a79c32013-03-10 03:50:271477 Renderbuffer* renderbuffer = NULL;
[email protected]0d6bfdc2011-11-02 01:32:201478 switch (target) {
1479 case GL_RENDERBUFFER:
[email protected]7cd76fd2013-06-02 21:11:111480 renderbuffer = state_.bound_renderbuffer.get();
[email protected]0d6bfdc2011-11-02 01:32:201481 break;
1482 default:
1483 NOTREACHED();
1484 break;
1485 }
[email protected]ee2a79c32013-03-10 03:50:271486 return renderbuffer;
[email protected]0d6bfdc2011-11-02 01:32:201487 }
1488
[email protected]f7b85372010-02-03 01:11:371489 // Validates the program and location for a glGetUniform call and returns
1490 // a SizeResult setup to receive the result. Returns true if glGetUniform
1491 // should be called.
1492 bool GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:121493 GLuint program, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:371494 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:121495 error::Error* error, GLint* real_location, GLuint* service_id,
1496 void** result, GLenum* result_type);
[email protected]f7b85372010-02-03 01:11:371497
[email protected]1078f912011-12-23 13:12:141498 // Computes the estimated memory used for the backbuffer and passes it to
1499 // the tracing system.
[email protected]260ddc4e2012-06-28 00:01:531500 size_t GetBackbufferMemoryTotal();
[email protected]1078f912011-12-23 13:12:141501
[email protected]a10b4a02012-11-26 23:09:501502 virtual bool WasContextLost() OVERRIDE;
[email protected]93a7d98f2013-07-11 00:04:221503 virtual bool WasContextLostByRobustnessExtension() OVERRIDE;
[email protected]c4485aad62012-12-17 10:19:091504 virtual void LoseContext(uint32 reset_status) OVERRIDE;
[email protected]38d139d2011-07-14 00:38:431505
[email protected]e51bdf32011-11-23 22:21:461506#if defined(OS_MACOSX)
1507 void ReleaseIOSurfaceForTexture(GLuint texture_id);
1508#endif
1509
[email protected]81375742012-06-08 00:04:001510 // Validates the combination of texture parameters. For example validates that
1511 // for a given format the specific type, level and targets are valid.
1512 // Synthesizes the correct GL error if invalid. Returns true if valid.
1513 bool ValidateTextureParameters(
1514 const char* function_name,
1515 GLenum target, GLenum format, GLenum type, GLint level);
1516
[email protected]ad84a3a2012-06-08 21:42:431517 bool ValidateCompressedTexDimensions(
1518 const char* function_name,
1519 GLint level, GLsizei width, GLsizei height, GLenum format);
1520 bool ValidateCompressedTexFuncData(
1521 const char* function_name,
1522 GLsizei width, GLsizei height, GLenum format, size_t size);
1523 bool ValidateCompressedTexSubDimensions(
1524 const char* function_name,
1525 GLenum target, GLint level, GLint xoffset, GLint yoffset,
1526 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:351527 Texture* texture);
[email protected]ad84a3a2012-06-08 21:42:431528
[email protected]ab09b612013-03-11 22:11:511529 void RenderWarning(const char* filename, int line, const std::string& msg);
1530 void PerformanceWarning(
1531 const char* filename, int line, const std::string& msg);
[email protected]0f8afe82012-05-14 23:43:011532
[email protected]62e155e2012-10-23 22:43:151533 const FeatureInfo::FeatureFlags& features() const {
1534 return feature_info_->feature_flags();
1535 }
1536
1537 const FeatureInfo::Workarounds& workarounds() const {
1538 return feature_info_->workarounds();
1539 }
1540
[email protected]a7266a92012-06-28 02:11:081541 bool ShouldDeferDraws() {
1542 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341543 framebuffer_state_.bound_draw_framebuffer.get() == NULL &&
[email protected]a7266a92012-06-28 02:11:081544 surface_->DeferDraws();
1545 }
1546
[email protected]09e17272012-11-30 10:30:441547 bool ShouldDeferReads() {
1548 return !offscreen_target_frame_buffer_.get() &&
[email protected]9d3b2e12013-10-02 01:04:341549 framebuffer_state_.bound_read_framebuffer.get() == NULL &&
[email protected]09e17272012-11-30 10:30:441550 surface_->DeferDraws();
1551 }
1552
[email protected]c76fe672013-12-13 23:30:221553 error::Error WillAccessBoundFramebufferForDraw() {
1554 if (ShouldDeferDraws())
1555 return error::kDeferCommandUntilLater;
1556 if (!offscreen_target_frame_buffer_.get() &&
1557 !framebuffer_state_.bound_draw_framebuffer.get() &&
1558 !surface_->SetBackbufferAllocation(true))
1559 return error::kLostContext;
1560 return error::kNoError;
1561 }
1562
1563 error::Error WillAccessBoundFramebufferForRead() {
1564 if (ShouldDeferReads())
1565 return error::kDeferCommandUntilLater;
1566 if (!offscreen_target_frame_buffer_.get() &&
1567 !framebuffer_state_.bound_read_framebuffer.get() &&
1568 !surface_->SetBackbufferAllocation(true))
1569 return error::kLostContext;
1570 return error::kNoError;
1571 }
1572
[email protected]5a36dc132013-07-23 23:17:551573 void ProcessPendingReadPixels();
1574 void FinishReadPixels(const cmds::ReadPixels& c, GLuint buffer);
1575
[email protected]96449d2c2009-11-25 00:01:321576 // Generate a member function prototype for each command in an automated and
1577 // typesafe way.
1578 #define GLES2_CMD_OP(name) \
[email protected]f7a64ee2010-02-01 22:24:141579 Error Handle ## name( \
[email protected]ed9f9cd2013-02-27 21:12:351580 uint32 immediate_data_size, \
1581 const cmds::name& args); \
[email protected]96449d2c2009-11-25 00:01:321582
1583 GLES2_COMMAND_LIST(GLES2_CMD_OP)
1584
1585 #undef GLES2_CMD_OP
1586
[email protected]2f2d7042010-04-14 21:45:581587 // The GL context this decoder renders to on behalf of the client.
[email protected]fbe20372011-06-01 01:46:381588 scoped_refptr<gfx::GLSurface> surface_;
1589 scoped_refptr<gfx::GLContext> context_;
[email protected]d37231fa2010-04-09 21:16:021590
[email protected]a3ded6d2010-10-19 06:44:391591 // The ContextGroup for this decoder uses to track resources.
[email protected]ed9f9cd2013-02-27 21:12:351592 scoped_refptr<ContextGroup> group_;
[email protected]a3ded6d2010-10-19 06:44:391593
[email protected]1d82e822013-04-10 21:32:321594 DebugMarkerManager debug_marker_manager_;
1595 Logger logger_;
1596
[email protected]e259eb412012-10-13 05:47:241597 // All the state for this context.
1598 ContextState state_;
1599
[email protected]34ff8b0c2010-10-01 20:06:021600 // Current width and height of the offscreen frame buffer.
1601 gfx::Size offscreen_size_;
1602
[email protected]96449d2c2009-11-25 00:01:321603 // Util to help with GL.
1604 GLES2Util util_;
1605
[email protected]43410e92012-04-20 17:06:281606 // unpack flip y as last set by glPixelStorei
1607 bool unpack_flip_y_;
1608
[email protected]6c75c712012-06-19 15:43:171609 // unpack (un)premultiply alpha as last set by glPixelStorei
[email protected]43410e92012-04-20 17:06:281610 bool unpack_premultiply_alpha_;
[email protected]6c75c712012-06-19 15:43:171611 bool unpack_unpremultiply_alpha_;
[email protected]43410e92012-04-20 17:06:281612
[email protected]944b62f32012-09-27 02:20:461613 // Default vertex attribs manager, used when no VAOs are bound.
[email protected]ed9f9cd2013-02-27 21:12:351614 scoped_refptr<VertexAttribManager> default_vertex_attrib_manager_;
[email protected]07f54fcc2009-12-22 02:46:301615
[email protected]b1122982010-05-17 23:04:241616 // The buffer we bind to attrib 0 since OpenGL requires it (ES does not).
1617 GLuint attrib_0_buffer_id_;
1618
1619 // The value currently in attrib_0.
[email protected]af6380962012-11-29 23:24:131620 Vec4 attrib_0_value_;
[email protected]b1122982010-05-17 23:04:241621
[email protected]fc753442011-02-04 19:49:491622 // Whether or not the attrib_0 buffer holds the attrib_0_value.
1623 bool attrib_0_buffer_matches_value_;
1624
[email protected]b1122982010-05-17 23:04:241625 // The size of attrib 0.
1626 GLsizei attrib_0_size_;
1627
[email protected]8fbedc02010-11-18 18:43:401628 // The buffer used to simulate GL_FIXED attribs.
1629 GLuint fixed_attrib_buffer_id_;
1630
1631 // The size of fiixed attrib buffer.
1632 GLsizei fixed_attrib_buffer_size_;
1633
[email protected]b9363b22010-06-09 22:06:151634 // The offscreen frame buffer that the client renders to. With EGL, the
1635 // depth and stencil buffers are separate. With regular GL there is a single
1636 // packed depth stencil buffer in offscreen_target_depth_render_buffer_.
1637 // offscreen_target_stencil_render_buffer_ is unused.
[email protected]ed9f9cd2013-02-27 21:12:351638 scoped_ptr<BackFramebuffer> offscreen_target_frame_buffer_;
1639 scoped_ptr<BackTexture> offscreen_target_color_texture_;
1640 scoped_ptr<BackRenderbuffer> offscreen_target_color_render_buffer_;
1641 scoped_ptr<BackRenderbuffer> offscreen_target_depth_render_buffer_;
1642 scoped_ptr<BackRenderbuffer> offscreen_target_stencil_render_buffer_;
[email protected]34ff8b0c2010-10-01 20:06:021643 GLenum offscreen_target_color_format_;
1644 GLenum offscreen_target_depth_format_;
1645 GLenum offscreen_target_stencil_format_;
1646 GLsizei offscreen_target_samples_;
[email protected]8a61d872012-01-20 12:43:561647 GLboolean offscreen_target_buffer_preserved_;
[email protected]6217d392010-03-25 22:08:351648
[email protected]de26b3c2011-08-03 21:54:271649 // The copy that is saved when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:351650 scoped_ptr<BackFramebuffer> offscreen_saved_frame_buffer_;
1651 scoped_ptr<BackTexture> offscreen_saved_color_texture_;
[email protected]370eaf12013-05-18 09:19:491652 scoped_refptr<TextureRef>
[email protected]ed9f9cd2013-02-27 21:12:351653 offscreen_saved_color_texture_info_;
[email protected]de26b3c2011-08-03 21:54:271654
1655 // The copy that is used as the destination for multi-sample resolves.
[email protected]ed9f9cd2013-02-27 21:12:351656 scoped_ptr<BackFramebuffer> offscreen_resolved_frame_buffer_;
1657 scoped_ptr<BackTexture> offscreen_resolved_color_texture_;
[email protected]97872062010-11-03 19:07:051658 GLenum offscreen_saved_color_format_;
[email protected]6217d392010-03-25 22:08:351659
[email protected]882ba1e22012-03-08 19:02:531660 scoped_ptr<QueryManager> query_manager_;
[email protected]882ba1e22012-03-08 19:02:531661
[email protected]944b62f32012-09-27 02:20:461662 scoped_ptr<VertexArrayManager> vertex_array_manager_;
1663
[email protected]729c0b42013-05-26 02:05:071664 base::Callback<void(gfx::Size, float)> resize_callback_;
[email protected]22f320a2011-08-30 01:17:001665
[email protected]840a7e462013-02-27 01:29:511666 WaitSyncPointCallback wait_sync_point_callback_;
[email protected]43f28f832010-02-03 02:28:481667
[email protected]e3932abb2013-03-13 00:01:371668 ShaderCacheCallback shader_cache_callback_;
1669
[email protected]85a4ac22013-05-31 01:58:471670 scoped_ptr<AsyncPixelTransferManager> async_pixel_transfer_manager_;
[email protected]b0af4f52011-09-28 22:04:421671
[email protected]32fe9aa2011-01-21 23:47:131672 // The format of the back buffer_
1673 GLenum back_buffer_color_format_;
[email protected]297ca1c2011-06-20 23:08:461674 bool back_buffer_has_depth_;
1675 bool back_buffer_has_stencil_;
[email protected]32fe9aa2011-01-21 23:47:131676
[email protected]60f22d32012-12-12 00:31:581677 // Backbuffer attachments that are currently undefined.
1678 uint32 backbuffer_needs_clear_bits_;
1679
[email protected]a3a93e7b2010-08-28 00:48:561680 // The current decoder error.
1681 error::Error current_decoder_error_;
1682
[email protected]b1d2dcb2010-05-17 19:24:181683 bool use_shader_translator_;
[email protected]87fb6ab2012-06-13 22:28:041684 scoped_refptr<ShaderTranslator> vertex_translator_;
1685 scoped_refptr<ShaderTranslator> fragment_translator_;
[email protected]b1d2dcb2010-05-17 19:24:181686
[email protected]e82fb792011-09-22 00:33:291687 DisallowedFeatures disallowed_features_;
[email protected]c410da802011-03-14 19:17:411688
[email protected]915a59a12010-09-30 21:29:111689 // Cached from ContextGroup
[email protected]9438b012010-06-15 22:55:051690 const Validators* validators_;
[email protected]ed9f9cd2013-02-27 21:12:351691 scoped_refptr<FeatureInfo> feature_info_;
[email protected]9438b012010-06-15 22:55:051692
[email protected]65225772011-05-12 21:10:241693 int frame_number_;
1694
[email protected]706b69f2012-07-27 04:59:301695 bool has_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431696 GLenum reset_status_;
[email protected]93a7d98f2013-07-11 00:04:221697 bool reset_by_robustness_extension_;
[email protected]38d139d2011-07-14 00:38:431698
[email protected]f0d74742011-10-03 16:31:041699 // These flags are used to override the state of the shared feature_info_
1700 // member. Because the same FeatureInfo instance may be shared among many
1701 // contexts, the assumptions on the availablity of extensions in WebGL
1702 // contexts may be broken. These flags override the shared state to preserve
1703 // WebGL semantics.
1704 bool force_webgl_glsl_validation_;
1705 bool derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:491706 bool frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:131707 bool draw_buffers_explicitly_enabled_;
[email protected]f0d74742011-10-03 16:31:041708
[email protected]062c38b2012-01-18 03:25:101709 bool compile_shader_always_succeeds_;
1710
[email protected]cae20172012-12-07 00:06:191711 // Log extra info.
1712 bool service_logging_;
1713
[email protected]e51bdf32011-11-23 22:21:461714#if defined(OS_MACOSX)
1715 typedef std::map<GLuint, CFTypeRef> TextureToIOSurfaceMap;
1716 TextureToIOSurfaceMap texture_to_io_surface_map_;
1717#endif
1718
[email protected]43410e92012-04-20 17:06:281719 scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_;
1720
[email protected]1868a342012-11-07 15:56:021721 // Cached values of the currently assigned viewport dimensions.
1722 GLsizei viewport_max_width_;
1723 GLsizei viewport_max_height_;
1724
[email protected]63b465922012-09-06 02:04:521725 // Command buffer stats.
[email protected]63b465922012-09-06 02:04:521726 base::TimeDelta total_processing_commands_time_;
1727
[email protected]c986af502013-08-14 01:04:441728 // States related to each manager.
1729 DecoderTextureState texture_state_;
1730 DecoderFramebufferState framebuffer_state_;
1731
[email protected]fb97b662013-02-20 23:02:141732 scoped_ptr<GPUTracer> gpu_tracer_;
[email protected]8f9b8dd2013-09-12 18:05:131733 scoped_ptr<GPUStateTracer> gpu_state_tracer_;
[email protected]cac16542014-01-15 17:53:511734 int gpu_trace_level_;
1735 bool gpu_trace_commands_;
[email protected]94307712012-11-16 23:26:111736
[email protected]5a36dc132013-07-23 23:17:551737 std::queue<linked_ptr<FenceCallback> > pending_readpixel_fences_;
1738
[email protected]4a4c18b2013-09-13 22:50:101739 // Used to validate multisample renderbuffers if needed
1740 GLuint validation_texture_;
1741 GLuint validation_fbo_multisample_;
1742 GLuint validation_fbo_;
1743
[email protected]96449d2c2009-11-25 00:01:321744 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
1745};
1746
[email protected]ab09b612013-03-11 22:11:511747ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
[email protected]40621eb52013-10-08 15:40:301748 const char* function_name, ErrorState* error_state)
[email protected]ab09b612013-03-11 22:11:511749 : function_name_(function_name),
[email protected]40621eb52013-10-08 15:40:301750 error_state_(error_state) {
1751 ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351752}
1753
1754ScopedGLErrorSuppressor::~ScopedGLErrorSuppressor() {
[email protected]40621eb52013-10-08 15:40:301755 ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_, function_name_);
[email protected]6217d392010-03-25 22:08:351756}
1757
[email protected]ce296892013-10-24 22:04:361758static void RestoreCurrentTexture2DBindings(ContextState* state) {
1759 TextureUnit& info = state->texture_units[0];
1760 GLuint last_id;
1761 if (info.bound_texture_2d.get()) {
1762 last_id = info.bound_texture_2d->service_id();
1763 } else {
1764 last_id = 0;
1765 }
1766
1767 glBindTexture(GL_TEXTURE_2D, last_id);
1768 glActiveTexture(GL_TEXTURE0 + state->active_texture_unit);
1769}
1770
1771ScopedTexture2DBinder::ScopedTexture2DBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351772 GLuint id)
[email protected]ce296892013-10-24 22:04:361773 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511774 ScopedGLErrorSuppressor suppressor(
[email protected]ce296892013-10-24 22:04:361775 "ScopedTexture2DBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351776
1777 // TODO(apatrick): Check if there are any other states that need to be reset
1778 // before binding a new texture.
1779 glActiveTexture(GL_TEXTURE0);
1780 glBindTexture(GL_TEXTURE_2D, id);
1781}
1782
1783ScopedTexture2DBinder::~ScopedTexture2DBinder() {
[email protected]ab09b612013-03-11 22:11:511784 ScopedGLErrorSuppressor suppressor(
[email protected]ce296892013-10-24 22:04:361785 "ScopedTexture2DBinder::dtor", state_->GetErrorState());
1786 RestoreCurrentTexture2DBindings(state_);
[email protected]6217d392010-03-25 22:08:351787}
1788
[email protected]18e785a2013-10-09 03:29:411789ScopedRenderBufferBinder::ScopedRenderBufferBinder(ContextState* state,
[email protected]6217d392010-03-25 22:08:351790 GLuint id)
[email protected]18e785a2013-10-09 03:29:411791 : state_(state) {
[email protected]ab09b612013-03-11 22:11:511792 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411793 "ScopedRenderBufferBinder::ctor", state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351794 glBindRenderbufferEXT(GL_RENDERBUFFER, id);
1795}
1796
1797ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511798 ScopedGLErrorSuppressor suppressor(
[email protected]18e785a2013-10-09 03:29:411799 "ScopedRenderBufferBinder::dtor", state_->GetErrorState());
1800 state_->RestoreRenderbufferBindings();
[email protected]6217d392010-03-25 22:08:351801}
1802
1803ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
1804 GLuint id)
1805 : decoder_(decoder) {
[email protected]ab09b612013-03-11 22:11:511806 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301807 "ScopedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351808 glBindFramebufferEXT(GL_FRAMEBUFFER, id);
[email protected]70d34263c2013-01-09 00:27:451809 decoder->OnFboChanged();
[email protected]6217d392010-03-25 22:08:351810}
1811
1812ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
[email protected]ab09b612013-03-11 22:11:511813 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301814 "ScopedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]8e3e0662010-08-23 18:46:301815 decoder_->RestoreCurrentFramebufferBindings();
[email protected]6217d392010-03-25 22:08:351816}
1817
[email protected]34ff8b0c2010-10-01 20:06:021818ScopedResolvedFrameBufferBinder::ScopedResolvedFrameBufferBinder(
[email protected]de26b3c2011-08-03 21:54:271819 GLES2DecoderImpl* decoder, bool enforce_internal_framebuffer, bool internal)
[email protected]c0701082011-04-20 00:34:521820 : decoder_(decoder) {
[email protected]9d3b2e12013-10-02 01:04:341821 resolve_and_bind_ = (
1822 decoder_->offscreen_target_frame_buffer_.get() &&
1823 decoder_->IsOffscreenBufferMultisampled() &&
1824 (!decoder_->framebuffer_state_.bound_read_framebuffer.get() ||
1825 enforce_internal_framebuffer));
[email protected]34ff8b0c2010-10-01 20:06:021826 if (!resolve_and_bind_)
1827 return;
1828
[email protected]ab09b612013-03-11 22:11:511829 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301830 "ScopedResolvedFrameBufferBinder::ctor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:021831 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT,
1832 decoder_->offscreen_target_frame_buffer_->id());
[email protected]de26b3c2011-08-03 21:54:271833 GLuint targetid;
1834 if (internal) {
1835 if (!decoder_->offscreen_resolved_frame_buffer_.get()) {
1836 decoder_->offscreen_resolved_frame_buffer_.reset(
[email protected]ed9f9cd2013-02-27 21:12:351837 new BackFramebuffer(decoder_));
[email protected]de26b3c2011-08-03 21:54:271838 decoder_->offscreen_resolved_frame_buffer_->Create();
[email protected]ed9f9cd2013-02-27 21:12:351839 decoder_->offscreen_resolved_color_texture_.reset(
[email protected]ce296892013-10-24 22:04:361840 new BackTexture(decoder->memory_tracker(), &decoder->state_));
[email protected]de26b3c2011-08-03 21:54:271841 decoder_->offscreen_resolved_color_texture_->Create();
1842
1843 DCHECK(decoder_->offscreen_saved_color_format_);
1844 decoder_->offscreen_resolved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:091845 decoder_->offscreen_size_, decoder_->offscreen_saved_color_format_,
1846 false);
[email protected]de26b3c2011-08-03 21:54:271847 decoder_->offscreen_resolved_frame_buffer_->AttachRenderTexture(
1848 decoder_->offscreen_resolved_color_texture_.get());
1849 if (decoder_->offscreen_resolved_frame_buffer_->CheckStatus() !=
1850 GL_FRAMEBUFFER_COMPLETE) {
1851 LOG(ERROR) << "ScopedResolvedFrameBufferBinder failed "
1852 << "because offscreen resolved FBO was incomplete.";
1853 return;
1854 }
1855 }
1856 targetid = decoder_->offscreen_resolved_frame_buffer_->id();
1857 } else {
1858 targetid = decoder_->offscreen_saved_frame_buffer_->id();
1859 }
1860 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021861 const int width = decoder_->offscreen_size_.width();
1862 const int height = decoder_->offscreen_size_.height();
[email protected]8c3e68782010-10-27 16:41:181863 glDisable(GL_SCISSOR_TEST);
[email protected]f42f05b2013-11-15 21:46:181864 decoder->BlitFramebufferHelper(0,
1865 0,
1866 width,
1867 height,
1868 0,
1869 0,
1870 width,
1871 height,
1872 GL_COLOR_BUFFER_BIT,
1873 GL_NEAREST);
[email protected]de26b3c2011-08-03 21:54:271874 glBindFramebufferEXT(GL_FRAMEBUFFER, targetid);
[email protected]34ff8b0c2010-10-01 20:06:021875}
1876
1877ScopedResolvedFrameBufferBinder::~ScopedResolvedFrameBufferBinder() {
1878 if (!resolve_and_bind_)
1879 return;
1880
[email protected]ab09b612013-03-11 22:11:511881 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:301882 "ScopedResolvedFrameBufferBinder::dtor", decoder_->GetErrorState());
[email protected]34ff8b0c2010-10-01 20:06:021883 decoder_->RestoreCurrentFramebufferBindings();
[email protected]f731b9462012-10-30 00:35:221884 if (decoder_->state_.enable_flags.scissor_test) {
[email protected]8c3e68782010-10-27 16:41:181885 glEnable(GL_SCISSOR_TEST);
1886 }
[email protected]34ff8b0c2010-10-01 20:06:021887}
1888
[email protected]ce296892013-10-24 22:04:361889BackTexture::BackTexture(
1890 MemoryTracker* memory_tracker,
1891 ContextState* state)
1892 : memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
1893 state_(state),
[email protected]68e81a4a62012-12-13 01:16:481894 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:251895 id_(0) {
[email protected]6217d392010-03-25 22:08:351896}
1897
[email protected]ed9f9cd2013-02-27 21:12:351898BackTexture::~BackTexture() {
[email protected]6217d392010-03-25 22:08:351899 // This does not destroy the render texture because that would require that
1900 // the associated GL context was current. Just check that it was explicitly
1901 // destroyed.
1902 DCHECK_EQ(id_, 0u);
1903}
1904
[email protected]ed9f9cd2013-02-27 21:12:351905void BackTexture::Create() {
[email protected]40621eb52013-10-08 15:40:301906 ScopedGLErrorSuppressor suppressor("BackTexture::Create",
[email protected]ce296892013-10-24 22:04:361907 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351908 Destroy();
1909 glGenTextures(1, &id_);
[email protected]ce296892013-10-24 22:04:361910 ScopedTexture2DBinder binder(state_, id_);
[email protected]3a4d0c52011-06-29 23:11:581911 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1912 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1913 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1914 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
[email protected]62788802011-10-03 17:57:161915
1916 // TODO(apatrick): Attempt to diagnose crbug.com/97775. If SwapBuffers is
1917 // never called on an offscreen context, no data will ever be uploaded to the
1918 // saved offscreen color texture (it is deferred until to when SwapBuffers
1919 // is called). My idea is that some nvidia drivers might have a bug where
1920 // deleting a texture that has never been populated might cause a
1921 // crash.
1922 glTexImage2D(
1923 GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
[email protected]68e81a4a62012-12-13 01:16:481924
1925 bytes_allocated_ = 16u * 16u * 4u;
1926 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]6217d392010-03-25 22:08:351927}
1928
[email protected]ed9f9cd2013-02-27 21:12:351929bool BackTexture::AllocateStorage(
1930 const gfx::Size& size, GLenum format, bool zero) {
[email protected]6217d392010-03-25 22:08:351931 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:301932 ScopedGLErrorSuppressor suppressor("BackTexture::AllocateStorage",
[email protected]ce296892013-10-24 22:04:361933 state_->GetErrorState());
1934 ScopedTexture2DBinder binder(state_, id_);
[email protected]678a73f2012-12-19 19:22:091935 uint32 image_size = 0;
1936 GLES2Util::ComputeImageDataSizes(
1937 size.width(), size.height(), format, GL_UNSIGNED_BYTE, 8, &image_size,
1938 NULL, NULL);
1939
[email protected]7989c9e2013-01-23 06:39:261940 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) {
1941 return false;
1942 }
1943
[email protected]40d90a22013-04-09 03:39:551944 scoped_ptr<char[]> zero_data;
[email protected]678a73f2012-12-19 19:22:091945 if (zero) {
1946 zero_data.reset(new char[image_size]);
1947 memset(zero_data.get(), 0, image_size);
1948 }
[email protected]6217d392010-03-25 22:08:351949
[email protected]8f1d2aa2013-05-10 23:45:381950 glTexImage2D(GL_TEXTURE_2D,
1951 0, // mip level
1952 format,
1953 size.width(),
1954 size.height(),
1955 0, // border
1956 format,
1957 GL_UNSIGNED_BYTE,
1958 zero_data.get());
[email protected]6217d392010-03-25 22:08:351959
[email protected]d37231fa2010-04-09 21:16:021960 size_ = size;
1961
[email protected]1078f912011-12-23 13:12:141962 bool success = glGetError() == GL_NO_ERROR;
1963 if (success) {
[email protected]68e81a4a62012-12-13 01:16:481964 memory_tracker_.TrackMemFree(bytes_allocated_);
1965 bytes_allocated_ = image_size;
1966 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:141967 }
1968 return success;
[email protected]6217d392010-03-25 22:08:351969}
1970
[email protected]ed9f9cd2013-02-27 21:12:351971void BackTexture::Copy(const gfx::Size& size, GLenum format) {
[email protected]6217d392010-03-25 22:08:351972 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:301973 ScopedGLErrorSuppressor suppressor("BackTexture::Copy",
[email protected]ce296892013-10-24 22:04:361974 state_->GetErrorState());
1975 ScopedTexture2DBinder binder(state_, id_);
[email protected]6217d392010-03-25 22:08:351976 glCopyTexImage2D(GL_TEXTURE_2D,
1977 0, // level
[email protected]3a4d0c52011-06-29 23:11:581978 format,
[email protected]6217d392010-03-25 22:08:351979 0, 0,
1980 size.width(),
1981 size.height(),
1982 0); // border
1983}
1984
[email protected]ed9f9cd2013-02-27 21:12:351985void BackTexture::Destroy() {
[email protected]6217d392010-03-25 22:08:351986 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:301987 ScopedGLErrorSuppressor suppressor("BackTexture::Destroy",
[email protected]ce296892013-10-24 22:04:361988 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:351989 glDeleteTextures(1, &id_);
1990 id_ = 0;
1991 }
[email protected]68e81a4a62012-12-13 01:16:481992 memory_tracker_.TrackMemFree(bytes_allocated_);
1993 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:351994}
1995
[email protected]ed9f9cd2013-02-27 21:12:351996void BackTexture::Invalidate() {
[email protected]97872062010-11-03 19:07:051997 id_ = 0;
1998}
1999
[email protected]d5a28e452013-10-10 01:01:402000BackRenderbuffer::BackRenderbuffer(
2001 RenderbufferManager* renderbuffer_manager,
2002 MemoryTracker* memory_tracker,
2003 ContextState* state)
2004 : renderbuffer_manager_(renderbuffer_manager),
2005 memory_tracker_(memory_tracker, MemoryTracker::kUnmanaged),
2006 state_(state),
[email protected]68e81a4a62012-12-13 01:16:482007 bytes_allocated_(0),
[email protected]ff6493f2012-07-31 19:52:252008 id_(0) {
[email protected]6217d392010-03-25 22:08:352009}
2010
[email protected]ed9f9cd2013-02-27 21:12:352011BackRenderbuffer::~BackRenderbuffer() {
[email protected]6217d392010-03-25 22:08:352012 // This does not destroy the render buffer because that would require that
2013 // the associated GL context was current. Just check that it was explicitly
2014 // destroyed.
2015 DCHECK_EQ(id_, 0u);
2016}
2017
[email protected]ed9f9cd2013-02-27 21:12:352018void BackRenderbuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302019 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Create",
[email protected]d5a28e452013-10-10 01:01:402020 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352021 Destroy();
2022 glGenRenderbuffersEXT(1, &id_);
2023}
2024
[email protected]f42f05b2013-11-15 21:46:182025bool BackRenderbuffer::AllocateStorage(const FeatureInfo* feature_info,
2026 const gfx::Size& size,
2027 GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:352028 GLsizei samples) {
[email protected]ab09b612013-03-11 22:11:512029 ScopedGLErrorSuppressor suppressor(
[email protected]d5a28e452013-10-10 01:01:402030 "BackRenderbuffer::AllocateStorage", state_->GetErrorState());
2031 ScopedRenderBufferBinder binder(state_, id_);
[email protected]7989c9e2013-01-23 06:39:262032
2033 uint32 estimated_size = 0;
[email protected]d5a28e452013-10-10 01:01:402034 if (!renderbuffer_manager_->ComputeEstimatedRenderbufferSize(
[email protected]8e102e102013-09-20 22:50:232035 size.width(), size.height(), samples, format, &estimated_size)) {
[email protected]7989c9e2013-01-23 06:39:262036 return false;
2037 }
2038
2039 if (!memory_tracker_.EnsureGPUMemoryAvailable(estimated_size)) {
2040 return false;
2041 }
2042
[email protected]34ff8b0c2010-10-01 20:06:022043 if (samples <= 1) {
2044 glRenderbufferStorageEXT(GL_RENDERBUFFER,
2045 format,
2046 size.width(),
2047 size.height());
2048 } else {
[email protected]f42f05b2013-11-15 21:46:182049 GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(feature_info,
2050 GL_RENDERBUFFER,
2051 samples,
2052 format,
2053 size.width(),
2054 size.height());
[email protected]34ff8b0c2010-10-01 20:06:022055 }
[email protected]1078f912011-12-23 13:12:142056 bool success = glGetError() == GL_NO_ERROR;
2057 if (success) {
[email protected]d5a28e452013-10-10 01:01:402058 // Mark the previously allocated bytes as free.
[email protected]68e81a4a62012-12-13 01:16:482059 memory_tracker_.TrackMemFree(bytes_allocated_);
[email protected]7989c9e2013-01-23 06:39:262060 bytes_allocated_ = estimated_size;
[email protected]d5a28e452013-10-10 01:01:402061 // Track the newly allocated bytes.
[email protected]68e81a4a62012-12-13 01:16:482062 memory_tracker_.TrackMemAlloc(bytes_allocated_);
[email protected]1078f912011-12-23 13:12:142063 }
2064 return success;
[email protected]6217d392010-03-25 22:08:352065}
2066
[email protected]ed9f9cd2013-02-27 21:12:352067void BackRenderbuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352068 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302069 ScopedGLErrorSuppressor suppressor("BackRenderbuffer::Destroy",
[email protected]d5a28e452013-10-10 01:01:402070 state_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352071 glDeleteRenderbuffersEXT(1, &id_);
2072 id_ = 0;
2073 }
[email protected]68e81a4a62012-12-13 01:16:482074 memory_tracker_.TrackMemFree(bytes_allocated_);
2075 bytes_allocated_ = 0;
[email protected]6217d392010-03-25 22:08:352076}
2077
[email protected]ed9f9cd2013-02-27 21:12:352078void BackRenderbuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052079 id_ = 0;
2080}
2081
[email protected]ed9f9cd2013-02-27 21:12:352082BackFramebuffer::BackFramebuffer(GLES2DecoderImpl* decoder)
[email protected]6217d392010-03-25 22:08:352083 : decoder_(decoder),
2084 id_(0) {
2085}
2086
[email protected]ed9f9cd2013-02-27 21:12:352087BackFramebuffer::~BackFramebuffer() {
[email protected]6217d392010-03-25 22:08:352088 // This does not destroy the frame buffer because that would require that
2089 // the associated GL context was current. Just check that it was explicitly
2090 // destroyed.
2091 DCHECK_EQ(id_, 0u);
2092}
2093
[email protected]ed9f9cd2013-02-27 21:12:352094void BackFramebuffer::Create() {
[email protected]40621eb52013-10-08 15:40:302095 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Create",
2096 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352097 Destroy();
2098 glGenFramebuffersEXT(1, &id_);
2099}
2100
[email protected]ed9f9cd2013-02-27 21:12:352101void BackFramebuffer::AttachRenderTexture(BackTexture* texture) {
[email protected]6217d392010-03-25 22:08:352102 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512103 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302104 "BackFramebuffer::AttachRenderTexture", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352105 ScopedFrameBufferBinder binder(decoder_, id_);
2106 GLuint attach_id = texture ? texture->id() : 0;
2107 glFramebufferTexture2DEXT(GL_FRAMEBUFFER,
2108 GL_COLOR_ATTACHMENT0,
2109 GL_TEXTURE_2D,
2110 attach_id,
2111 0);
2112}
2113
[email protected]ed9f9cd2013-02-27 21:12:352114void BackFramebuffer::AttachRenderBuffer(GLenum target,
2115 BackRenderbuffer* render_buffer) {
[email protected]6217d392010-03-25 22:08:352116 DCHECK_NE(id_, 0u);
[email protected]ab09b612013-03-11 22:11:512117 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:302118 "BackFramebuffer::AttachRenderBuffer", decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352119 ScopedFrameBufferBinder binder(decoder_, id_);
2120 GLuint attach_id = render_buffer ? render_buffer->id() : 0;
2121 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER,
[email protected]b9363b22010-06-09 22:06:152122 target,
[email protected]6217d392010-03-25 22:08:352123 GL_RENDERBUFFER,
2124 attach_id);
2125}
2126
[email protected]ed9f9cd2013-02-27 21:12:352127void BackFramebuffer::Destroy() {
[email protected]6217d392010-03-25 22:08:352128 if (id_ != 0) {
[email protected]40621eb52013-10-08 15:40:302129 ScopedGLErrorSuppressor suppressor("BackFramebuffer::Destroy",
2130 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352131 glDeleteFramebuffersEXT(1, &id_);
2132 id_ = 0;
2133 }
2134}
2135
[email protected]ed9f9cd2013-02-27 21:12:352136void BackFramebuffer::Invalidate() {
[email protected]97872062010-11-03 19:07:052137 id_ = 0;
2138}
2139
[email protected]ed9f9cd2013-02-27 21:12:352140GLenum BackFramebuffer::CheckStatus() {
[email protected]6217d392010-03-25 22:08:352141 DCHECK_NE(id_, 0u);
[email protected]40621eb52013-10-08 15:40:302142 ScopedGLErrorSuppressor suppressor("BackFramebuffer::CheckStatus",
2143 decoder_->GetErrorState());
[email protected]6217d392010-03-25 22:08:352144 ScopedFrameBufferBinder binder(decoder_, id_);
2145 return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
2146}
2147
[email protected]aa7666122011-09-02 19:45:522148GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) {
2149 return new GLES2DecoderImpl(group);
[email protected]96449d2c2009-11-25 00:01:322150}
2151
[email protected]aa7666122011-09-02 19:45:522152GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group)
[email protected]a3ded6d2010-10-19 06:44:392153 : GLES2Decoder(),
[email protected]3b1ecc262011-08-03 22:49:572154 group_(group),
[email protected]1d82e822013-04-10 21:32:322155 logger_(&debug_marker_manager_),
[email protected]d3eba342013-04-18 21:11:502156 state_(group_->feature_info(), &logger_),
[email protected]43410e92012-04-20 17:06:282157 unpack_flip_y_(false),
2158 unpack_premultiply_alpha_(false),
[email protected]6c75c712012-06-19 15:43:172159 unpack_unpremultiply_alpha_(false),
[email protected]b1122982010-05-17 23:04:242160 attrib_0_buffer_id_(0),
[email protected]fc753442011-02-04 19:49:492161 attrib_0_buffer_matches_value_(true),
[email protected]b1122982010-05-17 23:04:242162 attrib_0_size_(0),
[email protected]8fbedc02010-11-18 18:43:402163 fixed_attrib_buffer_id_(0),
2164 fixed_attrib_buffer_size_(0),
[email protected]34ff8b0c2010-10-01 20:06:022165 offscreen_target_color_format_(0),
2166 offscreen_target_depth_format_(0),
2167 offscreen_target_stencil_format_(0),
2168 offscreen_target_samples_(0),
[email protected]8a61d872012-01-20 12:43:562169 offscreen_target_buffer_preserved_(true),
[email protected]97872062010-11-03 19:07:052170 offscreen_saved_color_format_(0),
[email protected]32fe9aa2011-01-21 23:47:132171 back_buffer_color_format_(0),
[email protected]297ca1c2011-06-20 23:08:462172 back_buffer_has_depth_(false),
2173 back_buffer_has_stencil_(false),
[email protected]60f22d32012-12-12 00:31:582174 backbuffer_needs_clear_bits_(0),
[email protected]a3a93e7b2010-08-28 00:48:562175 current_decoder_error_(error::kNoError),
[email protected]9438b012010-06-15 22:55:052176 use_shader_translator_(true),
[email protected]915a59a12010-09-30 21:29:112177 validators_(group_->feature_info()->validators()),
[email protected]b493ee622011-04-13 23:52:002178 feature_info_(group_->feature_info()),
[email protected]38d139d2011-07-14 00:38:432179 frame_number_(0),
[email protected]706b69f2012-07-27 04:59:302180 has_robustness_extension_(false),
[email protected]75c023c2011-08-22 23:54:512181 reset_status_(GL_NO_ERROR),
[email protected]93a7d98f2013-07-11 00:04:222182 reset_by_robustness_extension_(false),
[email protected]f0d74742011-10-03 16:31:042183 force_webgl_glsl_validation_(false),
[email protected]062c38b2012-01-18 03:25:102184 derivatives_explicitly_enabled_(false),
[email protected]70dc60932013-06-04 03:33:492185 frag_depth_explicitly_enabled_(false),
[email protected]aff39ac82013-06-08 04:53:132186 draw_buffers_explicitly_enabled_(false),
[email protected]43410e92012-04-20 17:06:282187 compile_shader_always_succeeds_(false),
[email protected]cae20172012-12-07 00:06:192188 service_logging_(CommandLine::ForCurrentProcess()->HasSwitch(
2189 switches::kEnableGPUServiceLoggingGPU)),
[email protected]1868a342012-11-07 15:56:022190 viewport_max_width_(0),
[email protected]4a4c18b2013-09-13 22:50:102191 viewport_max_height_(0),
[email protected]345ba902013-11-14 21:39:002192 texture_state_(group_->feature_info()
2193 ->workarounds()
2194 .texsubimage2d_faster_than_teximage2d),
[email protected]4a4c18b2013-09-13 22:50:102195 validation_texture_(0),
2196 validation_fbo_multisample_(0),
2197 validation_fbo_(0) {
[email protected]3b1ecc262011-08-03 22:49:572198 DCHECK(group);
2199
[email protected]b1122982010-05-17 23:04:242200 attrib_0_value_.v[0] = 0.0f;
2201 attrib_0_value_.v[1] = 0.0f;
2202 attrib_0_value_.v[2] = 0.0f;
2203 attrib_0_value_.v[3] = 1.0f;
[email protected]b9363b22010-06-09 22:06:152204
[email protected]c2f8c8402010-12-06 18:07:242205 // The shader translator is used for WebGL even when running on EGL
2206 // because additional restrictions are needed (like only enabling
2207 // GL_OES_standard_derivatives on demand). It is used for the unit
[email protected]4b7eba92013-01-08 02:23:562208 // tests because GLES2DecoderWithShaderTest.GetShaderInfoLogValidArgs passes
2209 // the empty string to CompileShader and this is not a valid shader.
2210 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL ||
[email protected]39ba4f02012-03-26 01:16:002211 CommandLine::ForCurrentProcess()->HasSwitch(
2212 switches::kDisableGLSLTranslator)) {
[email protected]b9363b22010-06-09 22:06:152213 use_shader_translator_ = false;
2214 }
[email protected]96449d2c2009-11-25 00:01:322215}
2216
[email protected]80eb6b52012-01-19 00:14:412217GLES2DecoderImpl::~GLES2DecoderImpl() {
2218}
2219
[email protected]c410da802011-03-14 19:17:412220bool GLES2DecoderImpl::Initialize(
[email protected]fbe20372011-06-01 01:46:382221 const scoped_refptr<gfx::GLSurface>& surface,
2222 const scoped_refptr<gfx::GLContext>& context,
[email protected]069944672012-04-25 20:52:232223 bool offscreen,
[email protected]c410da802011-03-14 19:17:412224 const gfx::Size& size,
[email protected]e82fb792011-09-22 00:33:292225 const DisallowedFeatures& disallowed_features,
[email protected]3c644d82011-06-20 19:58:242226 const std::vector<int32>& attribs) {
[email protected]3551cb202012-05-24 10:55:322227 TRACE_EVENT0("gpu", "GLES2DecoderImpl::Initialize");
[email protected]63c9b052012-05-17 18:27:382228 DCHECK(context->IsCurrent(surface.get()));
[email protected]66791e382010-07-14 20:48:302229 DCHECK(!context_.get());
2230
[email protected]55e136f2013-04-03 18:50:062231 set_initialized();
[email protected]bccc0f32014-01-10 03:18:082232 gpu_tracer_ = GPUTracer::Create(this);
[email protected]8f9b8dd2013-09-12 18:05:132233 gpu_state_tracer_ = GPUStateTracer::Create(&state_);
[email protected]cac16542014-01-15 17:53:512234 // TODO(vmiura): Enable changing gpu_trace_level_ at runtime
2235 gpu_trace_level_ = 2;
2236 gpu_trace_commands_ = false;
[email protected]fb97b662013-02-20 23:02:142237
[email protected]e844ae22012-01-14 03:36:262238 if (CommandLine::ForCurrentProcess()->HasSwitch(
2239 switches::kEnableGPUDebugging)) {
2240 set_debug(true);
2241 }
2242
[email protected]39ba4f02012-03-26 01:16:002243 if (CommandLine::ForCurrentProcess()->HasSwitch(
2244 switches::kEnableGPUCommandLogging)) {
2245 set_log_commands(true);
2246 }
2247
[email protected]062c38b2012-01-18 03:25:102248 compile_shader_always_succeeds_ = CommandLine::ForCurrentProcess()->HasSwitch(
2249 switches::kCompileShaderAlwaysSucceeds);
2250
[email protected]f62a5ab2011-05-23 20:34:152251
[email protected]63c9b052012-05-17 18:27:382252 // Take ownership of the context and surface. The surface can be replaced with
2253 // SetSurface.
[email protected]fbe20372011-06-01 01:46:382254 context_ = context;
[email protected]63c9b052012-05-17 18:27:382255 surface_ = surface;
[email protected]eb54a562010-01-20 21:55:182256
[email protected]65f7efe2013-11-28 03:11:472257 ContextCreationAttribHelper attrib_parser;
2258 if (!attrib_parser.Parse(attribs))
2259 return false;
2260
2261 // If the failIfMajorPerformanceCaveat context creation attribute was true
2262 // and we are using a software renderer, fail.
2263 if (attrib_parser.fail_if_major_perf_caveat_ &&
2264 feature_info_->feature_flags().is_swiftshader) {
2265 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
2266 Destroy(true);
2267 return false;
2268 }
2269
[email protected]956aec52013-09-05 15:41:192270 if (!group_->Initialize(this, disallowed_features)) {
[email protected]09ddb91f2011-04-14 23:16:222271 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group "
[email protected]a3ded6d2010-10-19 06:44:392272 << "failed to initialize.";
[email protected]1871a092011-10-10 21:46:422273 group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
[email protected]63c9b052012-05-17 18:27:382274 Destroy(true);
[email protected]ae1741092010-11-17 19:16:032275 return false;
[email protected]a3ded6d2010-10-19 06:44:392276 }
[email protected]b64c24952012-04-19 03:20:272277 CHECK_GL_ERROR();
[email protected]43410e92012-04-20 17:06:282278
[email protected]e82fb792011-09-22 00:33:292279 disallowed_features_ = disallowed_features;
[email protected]246a70452010-03-05 21:53:502280
[email protected]af6380962012-11-29 23:24:132281 state_.attrib_values.resize(group_->max_vertex_attribs());
[email protected]944b62f32012-09-27 02:20:462282 default_vertex_attrib_manager_ = new VertexAttribManager();
2283 default_vertex_attrib_manager_->Initialize(group_->max_vertex_attribs());
2284
[email protected]ab4fd7282012-10-12 16:25:572285 // vertex_attrib_manager is set to default_vertex_attrib_manager_ by this call
2286 DoBindVertexArrayOES(0);
[email protected]876f6fee2010-08-02 23:10:322287
[email protected]7cd76fd2013-06-02 21:11:112288 query_manager_.reset(new QueryManager(this, feature_info_.get()));
[email protected]944b62f32012-09-27 02:20:462289 vertex_array_manager_.reset(new VertexArrayManager());
[email protected]882ba1e22012-03-08 19:02:532290
[email protected]302ce6d2011-07-07 23:28:112291 util_.set_num_compressed_texture_formats(
2292 validators_->compressed_texture_format.GetValues().size());
2293
[email protected]1071e572011-02-09 20:00:122294 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2295 // We have to enable vertex array 0 on OpenGL or it won't render. Note that
2296 // OpenGL ES 2.0 does not have this issue.
2297 glEnableVertexAttribArray(0);
2298 }
[email protected]b1122982010-05-17 23:04:242299 glGenBuffersARB(1, &attrib_0_buffer_id_);
2300 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
2301 glVertexAttribPointer(0, 1, GL_FLOAT, GL_FALSE, 0, NULL);
2302 glBindBuffer(GL_ARRAY_BUFFER, 0);
[email protected]8fbedc02010-11-18 18:43:402303 glGenBuffersARB(1, &fixed_attrib_buffer_id_);
[email protected]f39f4b3f2010-05-12 17:04:082304
[email protected]1868a342012-11-07 15:56:022305 state_.texture_units.resize(group_->max_texture_units());
2306 for (uint32 tt = 0; tt < state_.texture_units.size(); ++tt) {
[email protected]00f893d2010-08-24 18:55:492307 glActiveTexture(GL_TEXTURE0 + tt);
[email protected]61eeb33f2011-07-26 15:30:312308 // We want the last bind to be 2D.
[email protected]370eaf12013-05-18 09:19:492309 TextureRef* ref;
[email protected]62e155e2012-10-23 22:43:152310 if (features().oes_egl_image_external) {
[email protected]370eaf12013-05-18 09:19:492311 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072312 GL_TEXTURE_EXTERNAL_OES);
[email protected]370eaf12013-05-18 09:19:492313 state_.texture_units[tt].bound_texture_external_oes = ref;
2314 glBindTexture(GL_TEXTURE_EXTERNAL_OES, ref->service_id());
[email protected]61eeb33f2011-07-26 15:30:312315 }
[email protected]62e155e2012-10-23 22:43:152316 if (features().arb_texture_rectangle) {
[email protected]370eaf12013-05-18 09:19:492317 ref = texture_manager()->GetDefaultTextureInfo(
[email protected]02965c22013-03-09 02:40:072318 GL_TEXTURE_RECTANGLE_ARB);
[email protected]370eaf12013-05-18 09:19:492319 state_.texture_units[tt].bound_texture_rectangle_arb = ref;
2320 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, ref->service_id());
[email protected]e51bdf32011-11-23 22:21:462321 }
[email protected]370eaf12013-05-18 09:19:492322 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_CUBE_MAP);
2323 state_.texture_units[tt].bound_texture_cube_map = ref;
2324 glBindTexture(GL_TEXTURE_CUBE_MAP, ref->service_id());
2325 ref = texture_manager()->GetDefaultTextureInfo(GL_TEXTURE_2D);
2326 state_.texture_units[tt].bound_texture_2d = ref;
2327 glBindTexture(GL_TEXTURE_2D, ref->service_id());
[email protected]1958e0e2010-04-22 05:17:152328 }
[email protected]00f893d2010-08-24 18:55:492329 glActiveTexture(GL_TEXTURE0);
[email protected]246a70452010-03-05 21:53:502330 CHECK_GL_ERROR();
2331
[email protected]069944672012-04-25 20:52:232332 if (offscreen) {
[email protected]34ff8b0c2010-10-01 20:06:022333 if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 &&
[email protected]b0609652012-12-14 07:24:542334 features().chromium_framebuffer_multisample) {
[email protected]34ff8b0c2010-10-01 20:06:022335 // Per ext_framebuffer_multisample spec, need max bound on sample count.
[email protected]0b1e9d72010-11-11 16:29:432336 // max_sample_count must be initialized to a sane value. If
2337 // glGetIntegerv() throws a GL error, it leaves its argument unchanged.
2338 GLint max_sample_count = 1;
[email protected]34ff8b0c2010-10-01 20:06:022339 glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_sample_count);
2340 offscreen_target_samples_ = std::min(attrib_parser.samples_,
2341 max_sample_count);
2342 } else {
2343 offscreen_target_samples_ = 1;
2344 }
[email protected]8a61d872012-01-20 12:43:562345 offscreen_target_buffer_preserved_ = attrib_parser.buffer_preserved_;
[email protected]34ff8b0c2010-10-01 20:06:022346
2347 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
2348 const bool rgb8_supported =
2349 context_->HasExtension("GL_OES_rgb8_rgba8");
2350 // The only available default render buffer formats in GLES2 have very
2351 // little precision. Don't enable multisampling unless 8-bit render
2352 // buffer formats are available--instead fall back to 8-bit textures.
2353 if (rgb8_supported && offscreen_target_samples_ > 1) {
2354 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2355 GL_RGBA8 : GL_RGB8;
2356 } else {
2357 offscreen_target_samples_ = 1;
2358 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2359 GL_RGBA : GL_RGB;
2360 }
2361
2362 // ANGLE only supports packed depth/stencil formats, so use it if it is
2363 // available.
2364 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182365 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272366 VLOG(1) << "GL_OES_packed_depth_stencil "
2367 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]71ee3642010-10-14 18:08:002368 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2369 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022370 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2371 offscreen_target_stencil_format_ = 0;
2372 } else {
2373 // It may be the case that this depth/stencil combination is not
2374 // supported, but this will be checked later by CheckFramebufferStatus.
2375 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2376 GL_DEPTH_COMPONENT16 : 0;
2377 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2378 GL_STENCIL_INDEX8 : 0;
2379 }
2380 } else {
2381 offscreen_target_color_format_ = attrib_parser.alpha_size_ > 0 ?
2382 GL_RGBA : GL_RGB;
2383
2384 // If depth is requested at all, use the packed depth stencil format if
2385 // it's available, as some desktop GL drivers don't support any non-packed
2386 // formats for depth attachments.
2387 const bool depth24_stencil8_supported =
[email protected]f42f05b2013-11-15 21:46:182388 feature_info_->feature_flags().packed_depth24_stencil8;
[email protected]d366c482010-10-20 00:11:272389 VLOG(1) << "GL_EXT_packed_depth_stencil "
2390 << (depth24_stencil8_supported ? "" : "not ") << "supported.";
[email protected]34ff8b0c2010-10-01 20:06:022391
[email protected]71ee3642010-10-14 18:08:002392 if ((attrib_parser.depth_size_ > 0 || attrib_parser.stencil_size_ > 0) &&
2393 depth24_stencil8_supported) {
[email protected]34ff8b0c2010-10-01 20:06:022394 offscreen_target_depth_format_ = GL_DEPTH24_STENCIL8;
2395 offscreen_target_stencil_format_ = 0;
2396 } else {
2397 offscreen_target_depth_format_ = attrib_parser.depth_size_ > 0 ?
2398 GL_DEPTH_COMPONENT : 0;
2399 offscreen_target_stencil_format_ = attrib_parser.stencil_size_ > 0 ?
2400 GL_STENCIL_INDEX : 0;
2401 }
2402 }
2403
[email protected]97872062010-11-03 19:07:052404 offscreen_saved_color_format_ = attrib_parser.alpha_size_ > 0 ?
2405 GL_RGBA : GL_RGB;
2406
[email protected]6217d392010-03-25 22:08:352407 // Create the target frame buffer. This is the one that the client renders
2408 // directly to.
[email protected]ed9f9cd2013-02-27 21:12:352409 offscreen_target_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]6217d392010-03-25 22:08:352410 offscreen_target_frame_buffer_->Create();
[email protected]34ff8b0c2010-10-01 20:06:022411 // Due to GLES2 format limitations, either the color texture (for
2412 // non-multisampling) or the color render buffer (for multisampling) will be
2413 // attached to the offscreen frame buffer. The render buffer has more
2414 // limited formats available to it, but the texture can't do multisampling.
2415 if (IsOffscreenBufferMultisampled()) {
[email protected]d5a28e452013-10-10 01:01:402416 offscreen_target_color_render_buffer_.reset(new BackRenderbuffer(
2417 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022418 offscreen_target_color_render_buffer_->Create();
2419 } else {
[email protected]ce296892013-10-24 22:04:362420 offscreen_target_color_texture_.reset(new BackTexture(
2421 memory_tracker(), &state_));
[email protected]34ff8b0c2010-10-01 20:06:022422 offscreen_target_color_texture_->Create();
2423 }
[email protected]d5a28e452013-10-10 01:01:402424 offscreen_target_depth_render_buffer_.reset(new BackRenderbuffer(
2425 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152426 offscreen_target_depth_render_buffer_->Create();
[email protected]d5a28e452013-10-10 01:01:402427 offscreen_target_stencil_render_buffer_.reset(new BackRenderbuffer(
2428 renderbuffer_manager(), memory_tracker(), &state_));
[email protected]b9363b22010-06-09 22:06:152429 offscreen_target_stencil_render_buffer_->Create();
[email protected]6217d392010-03-25 22:08:352430
2431 // Create the saved offscreen texture. The target frame buffer is copied
2432 // here when SwapBuffers is called.
[email protected]ed9f9cd2013-02-27 21:12:352433 offscreen_saved_frame_buffer_.reset(new BackFramebuffer(this));
[email protected]34ff8b0c2010-10-01 20:06:022434 offscreen_saved_frame_buffer_->Create();
2435 //
[email protected]ce296892013-10-24 22:04:362436 offscreen_saved_color_texture_.reset(new BackTexture(
2437 memory_tracker(), &state_));
[email protected]6217d392010-03-25 22:08:352438 offscreen_saved_color_texture_->Create();
2439
[email protected]6217d392010-03-25 22:08:352440 // Allocate the render buffers at their initial size and check the status
2441 // of the frame buffers is okay.
[email protected]799b4b22011-08-22 17:09:592442 if (!ResizeOffscreenFrameBuffer(size)) {
[email protected]d0498742010-09-20 20:27:012443 LOG(ERROR) << "Could not allocate offscreen buffer storage.";
[email protected]63c9b052012-05-17 18:27:382444 Destroy(true);
[email protected]6217d392010-03-25 22:08:352445 return false;
2446 }
2447
[email protected]678a73f2012-12-19 19:22:092448 // Allocate the offscreen saved color texture.
2449 DCHECK(offscreen_saved_color_format_);
2450 offscreen_saved_color_texture_->AllocateStorage(
2451 gfx::Size(1, 1), offscreen_saved_color_format_, true);
2452
2453 offscreen_saved_frame_buffer_->AttachRenderTexture(
2454 offscreen_saved_color_texture_.get());
2455 if (offscreen_saved_frame_buffer_->CheckStatus() !=
2456 GL_FRAMEBUFFER_COMPLETE) {
2457 LOG(ERROR) << "Offscreen saved FBO was incomplete.";
2458 Destroy(true);
2459 return false;
2460 }
2461
[email protected]6217d392010-03-25 22:08:352462 // Bind to the new default frame buffer (the offscreen target frame buffer).
2463 // This should now be associated with ID zero.
2464 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
[email protected]62e65f02013-05-29 22:28:102465 } else {
2466 glBindFramebufferEXT(GL_FRAMEBUFFER, GetBackbufferServiceId());
2467 // These are NOT if the back buffer has these proprorties. They are
2468 // if we want the command buffer to enforce them regardless of what
2469 // the real backbuffer is assuming the real back buffer gives us more than
2470 // we ask for. In other words, if we ask for RGB and we get RGBA then we'll
2471 // make it appear RGB. If on the other hand we ask for RGBA nd get RGB we
2472 // can't do anything about that.
2473
2474 GLint v = 0;
2475 glGetIntegerv(GL_ALPHA_BITS, &v);
2476 // This checks if the user requested RGBA and we have RGBA then RGBA. If the
2477 // user requested RGB then RGB. If the user did not specify a preference
2478 // than use whatever we were given. Same for DEPTH and STENCIL.
2479 back_buffer_color_format_ =
2480 (attrib_parser.alpha_size_ != 0 && v > 0) ? GL_RGBA : GL_RGB;
2481 glGetIntegerv(GL_DEPTH_BITS, &v);
2482 back_buffer_has_depth_ = attrib_parser.depth_size_ != 0 && v > 0;
2483 glGetIntegerv(GL_STENCIL_BITS, &v);
2484 back_buffer_has_stencil_ = attrib_parser.stencil_size_ != 0 && v > 0;
[email protected]6217d392010-03-25 22:08:352485 }
2486
[email protected]76a0ee102010-04-07 21:03:042487 // OpenGL ES 2.0 implicitly enables the desktop GL capability
2488 // VERTEX_PROGRAM_POINT_SIZE and doesn't expose this enum. This fact
2489 // isn't well documented; it was discovered in the Khronos OpenGL ES
[email protected]c1d82b62010-09-20 22:43:372490 // mailing list archives. It also implicitly enables the desktop GL
2491 // capability GL_POINT_SPRITE to provide access to the gl_PointCoord
2492 // variable in fragment shaders.
[email protected]b9363b22010-06-09 22:06:152493 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
2494 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
[email protected]c1d82b62010-09-20 22:43:372495 glEnable(GL_POINT_SPRITE);
[email protected]b9363b22010-06-09 22:06:152496 }
[email protected]de17df392010-04-23 21:09:412497
[email protected]706b69f2012-07-27 04:59:302498 has_robustness_extension_ =
2499 context->HasExtension("GL_ARB_robustness") ||
2500 context->HasExtension("GL_EXT_robustness");
[email protected]38d139d2011-07-14 00:38:432501
[email protected]c2f8c8402010-12-06 18:07:242502 if (!InitializeShaderTranslator()) {
2503 return false;
[email protected]de17df392010-04-23 21:09:412504 }
[email protected]76a0ee102010-04-07 21:03:042505
[email protected]e259eb412012-10-13 05:47:242506 state_.viewport_width = size.width();
2507 state_.viewport_height = size.height();
[email protected]43410e92012-04-20 17:06:282508
[email protected]5904806b2012-05-08 18:10:222509 GLint viewport_params[4] = { 0 };
[email protected]43410e92012-04-20 17:06:282510 glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params);
[email protected]1868a342012-11-07 15:56:022511 viewport_max_width_ = viewport_params[0];
2512 viewport_max_height_ = viewport_params[1];
[email protected]43410e92012-04-20 17:06:282513
[email protected]88a61bf2012-10-27 13:00:422514 state_.scissor_width = state_.viewport_width;
2515 state_.scissor_height = state_.viewport_height;
2516
[email protected]11f3e702012-06-19 19:00:012517 // Set all the default state because some GL drivers get it wrong.
[email protected]f731b9462012-10-30 00:35:222518 state_.InitCapabilities();
2519 state_.InitState();
[email protected]e259eb412012-10-13 05:47:242520 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]11f3e702012-06-19 19:00:012521
2522 DoBindBuffer(GL_ARRAY_BUFFER, 0);
2523 DoBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2524 DoBindFramebuffer(GL_FRAMEBUFFER, 0);
2525 DoBindRenderbuffer(GL_RENDERBUFFER, 0);
2526
[email protected]88cfd132013-07-11 00:59:002527 bool call_gl_clear = true;
2528#if defined(OS_ANDROID)
2529 // Temporary workaround for Android WebView because this clear ignores the
2530 // clip and corrupts that external UI of the App. Not calling glClear is ok
2531 // because the system already clears the buffer before each draw. Proper
2532 // fix might be setting the scissor clip properly before initialize. See
2533 // crbug.com/259023 for details.
2534 call_gl_clear = surface_->GetHandle();
2535#endif
2536 if (call_gl_clear) {
2537 // Clear the backbuffer.
2538 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2539 }
[email protected]561cc0a62013-05-07 18:34:452540
[email protected]62e155e2012-10-23 22:43:152541 if (feature_info_->workarounds().reverse_point_sprite_coord_origin) {
[email protected]dd289a5d62012-06-30 22:05:462542 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
2543 }
[email protected]dd289a5d62012-06-30 22:05:462544
[email protected]9b753992013-04-27 02:04:412545 if (feature_info_->workarounds().unbind_fbo_on_context_switch) {
2546 context_->SetUnbindFboOnMakeCurrent();
[email protected]85cb4682013-04-20 00:54:242547 }
[email protected]85cb4682013-04-20 00:54:242548
[email protected]40245ccf2013-11-13 04:00:492549 if (feature_info_->workarounds().release_image_after_use) {
2550 image_manager()->SetReleaseAfterUse();
2551 }
2552
[email protected]97419c02013-04-10 02:52:382553 // Only compositor contexts are known to use only the subset of GL
2554 // that can be safely migrated between the iGPU and the dGPU. Mark
2555 // those contexts as safe to forcibly transition between the GPUs.
2556 // http://crbug.com/180876, http://crbug.com/227228
2557 if (!offscreen)
2558 context_->SetSafeToForceGpuSwitch();
2559
[email protected]85a4ac22013-05-31 01:58:472560 async_pixel_transfer_manager_.reset(
[email protected]498b5c072013-06-04 19:30:072561 AsyncPixelTransferManager::Create(context.get()));
2562 async_pixel_transfer_manager_->Initialize(texture_manager());
[email protected]32145a92012-12-17 09:01:592563
[email protected]91c94eb2013-10-22 10:32:542564 framebuffer_manager()->AddObserver(this);
2565
[email protected]246a70452010-03-05 21:53:502566 return true;
[email protected]96449d2c2009-11-25 00:01:322567}
2568
[email protected]6d668892013-12-04 21:37:122569Capabilities GLES2DecoderImpl::GetCapabilities() {
2570 DCHECK(initialized());
2571
2572 Capabilities caps;
2573
2574 caps.fast_npot_mo8_textures =
2575 feature_info_->workarounds().enable_chromium_fast_npot_mo8_textures;
2576 caps.egl_image_external =
2577 feature_info_->feature_flags().oes_egl_image_external;
2578 caps.texture_format_bgra8888 =
2579 feature_info_->feature_flags().ext_texture_format_bgra8888;
2580 caps.texture_format_etc1 =
2581 feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
2582 caps.texture_rectangle = feature_info_->feature_flags().arb_texture_rectangle;
2583 caps.texture_usage = feature_info_->feature_flags().angle_texture_usage;
2584 caps.texture_storage = feature_info_->feature_flags().ext_texture_storage;
2585 caps.discard_framebuffer =
2586 feature_info_->feature_flags().ext_discard_framebuffer;
2587
2588#if defined(OS_MACOSX)
2589 // This is unconditionally true on mac, no need to test for it at runtime.
2590 caps.iosurface = true;
2591#endif
2592
[email protected]35387b3b2014-01-11 22:50:112593 caps.post_sub_buffer = surface_->HasExtension("GL_CHROMIUM_post_sub_buffer");
[email protected]6d668892013-12-04 21:37:122594
2595 return caps;
2596}
2597
[email protected]302ce6d2011-07-07 23:28:112598void GLES2DecoderImpl::UpdateCapabilities() {
2599 util_.set_num_compressed_texture_formats(
2600 validators_->compressed_texture_format.GetValues().size());
2601 util_.set_num_shader_binary_formats(
2602 validators_->shader_binary_format.GetValues().size());
2603}
2604
[email protected]c2f8c8402010-12-06 18:07:242605bool GLES2DecoderImpl::InitializeShaderTranslator() {
[email protected]a5d3dad2012-05-26 04:34:442606 TRACE_EVENT0("gpu", "GLES2DecoderImpl::InitializeShaderTranslator");
2607
[email protected]c2f8c8402010-12-06 18:07:242608 if (!use_shader_translator_) {
2609 return true;
2610 }
2611 ShBuiltInResources resources;
2612 ShInitBuiltInResources(&resources);
2613 resources.MaxVertexAttribs = group_->max_vertex_attribs();
2614 resources.MaxVertexUniformVectors =
2615 group_->max_vertex_uniform_vectors();
2616 resources.MaxVaryingVectors = group_->max_varying_vectors();
2617 resources.MaxVertexTextureImageUnits =
2618 group_->max_vertex_texture_image_units();
2619 resources.MaxCombinedTextureImageUnits = group_->max_texture_units();
2620 resources.MaxTextureImageUnits = group_->max_texture_image_units();
2621 resources.MaxFragmentUniformVectors =
2622 group_->max_fragment_uniform_vectors();
[email protected]2f143d482013-03-14 18:04:492623 resources.MaxDrawBuffers = group_->max_draw_buffers();
[email protected]a0b78142013-05-23 00:47:242624 resources.MaxExpressionComplexity = 256;
2625 resources.MaxCallStackDepth = 256;
[email protected]f0d74742011-10-03 16:31:042626
[email protected]9e98f61b2013-03-05 02:21:142627#if (ANGLE_SH_VERSION >= 110)
[email protected]46c86752013-05-21 05:08:392628 GLint range[2] = { 0, 0 };
[email protected]8dc1bf92013-03-12 03:58:212629 GLint precision = 0;
2630 GetShaderPrecisionFormatImpl(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
2631 range, &precision);
[email protected]448e459e2013-06-12 17:00:412632 resources.FragmentPrecisionHigh =
2633 PrecisionMeetsSpecForHighpFloat(range[0], range[1], precision);
[email protected]9e98f61b2013-03-05 02:21:142634#endif
2635
[email protected]f0d74742011-10-03 16:31:042636 if (force_webgl_glsl_validation_) {
2637 resources.OES_standard_derivatives = derivatives_explicitly_enabled_;
[email protected]70dc60932013-06-04 03:33:492638 resources.EXT_frag_depth = frag_depth_explicitly_enabled_;
[email protected]aff39ac82013-06-08 04:53:132639 resources.EXT_draw_buffers = draw_buffers_explicitly_enabled_;
[email protected]cd8f1892013-09-05 00:14:442640 if (!draw_buffers_explicitly_enabled_)
2641 resources.MaxDrawBuffers = 1;
[email protected]f0d74742011-10-03 16:31:042642 } else {
2643 resources.OES_standard_derivatives =
[email protected]62e155e2012-10-23 22:43:152644 features().oes_standard_derivatives ? 1 : 0;
[email protected]e51bdf32011-11-23 22:21:462645 resources.ARB_texture_rectangle =
[email protected]62e155e2012-10-23 22:43:152646 features().arb_texture_rectangle ? 1 : 0;
[email protected]70e7bb12012-09-29 14:01:062647 resources.OES_EGL_image_external =
[email protected]62e155e2012-10-23 22:43:152648 features().oes_egl_image_external ? 1 : 0;
[email protected]2f143d482013-03-14 18:04:492649 resources.EXT_draw_buffers =
2650 features().ext_draw_buffers ? 1 : 0;
[email protected]70dc60932013-06-04 03:33:492651 resources.EXT_frag_depth =
2652 features().ext_frag_depth ? 1 : 0;
[email protected]f0d74742011-10-03 16:31:042653 }
2654
[email protected]26b61442013-03-17 16:12:012655 ShShaderSpec shader_spec = force_webgl_glsl_validation_ ? SH_WEBGL_SPEC
2656 : SH_GLES2_SPEC;
[email protected]6aedcdc2013-01-24 01:25:052657 if (shader_spec == SH_WEBGL_SPEC && features().enable_shader_name_hashing)
[email protected]3d944a82013-02-12 19:09:022658#if !defined(ANGLE_SH_VERSION) || ANGLE_SH_VERSION < 108
[email protected]6aedcdc2013-01-24 01:25:052659 resources.HashFunction = &CityHashForAngle;
[email protected]3d944a82013-02-12 19:09:022660#else
2661 resources.HashFunction = &CityHash64;
2662#endif
[email protected]6aedcdc2013-01-24 01:25:052663 else
2664 resources.HashFunction = NULL;
[email protected]a2a0fe762011-09-20 00:59:122665 ShaderTranslatorInterface::GlslImplementationType implementation_type =
2666 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2 ?
2667 ShaderTranslatorInterface::kGlslES : ShaderTranslatorInterface::kGlsl;
[email protected]a6739bc2013-09-07 04:45:212668 int driver_bug_workarounds = 0;
2669 if (workarounds().needs_glsl_built_in_function_emulation)
2670 driver_bug_workarounds |= SH_EMULATE_BUILT_IN_FUNCTIONS;
[email protected]81187c62013-09-09 23:54:542671 if (workarounds().init_gl_position_in_vertex_shader)
2672 driver_bug_workarounds |= SH_INIT_GL_POSITION;
[email protected]f0c87602013-10-17 19:34:112673 if (workarounds().unfold_short_circuit_as_ternary_operation)
2674 driver_bug_workarounds |= SH_UNFOLD_SHORT_CIRCUIT;
[email protected]87fb6ab2012-06-13 22:28:042675
2676 ShaderTranslatorCache* cache = ShaderTranslatorCache::GetInstance();
2677 vertex_translator_ = cache->GetTranslator(
2678 SH_VERTEX_SHADER, shader_spec, &resources,
[email protected]a6739bc2013-09-07 04:45:212679 implementation_type,
2680 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042681 if (!vertex_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242682 LOG(ERROR) << "Could not initialize vertex shader translator.";
[email protected]63c9b052012-05-17 18:27:382683 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242684 return false;
2685 }
[email protected]87fb6ab2012-06-13 22:28:042686
2687 fragment_translator_ = cache->GetTranslator(
2688 SH_FRAGMENT_SHADER, shader_spec, &resources,
[email protected]a6739bc2013-09-07 04:45:212689 implementation_type,
2690 static_cast<ShCompileOptions>(driver_bug_workarounds));
[email protected]87fb6ab2012-06-13 22:28:042691 if (!fragment_translator_.get()) {
[email protected]c2f8c8402010-12-06 18:07:242692 LOG(ERROR) << "Could not initialize fragment shader translator.";
[email protected]63c9b052012-05-17 18:27:382693 Destroy(true);
[email protected]c2f8c8402010-12-06 18:07:242694 return false;
2695 }
2696 return true;
2697}
2698
[email protected]ae51d192010-04-27 00:48:032699bool GLES2DecoderImpl::GenBuffersHelper(GLsizei n, const GLuint* client_ids) {
[email protected]a93bb842010-02-16 23:03:472700 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352701 if (GetBuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032702 return false;
2703 }
2704 }
[email protected]40d90a22013-04-09 03:39:552705 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032706 glGenBuffersARB(n, service_ids.get());
2707 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352708 CreateBuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032709 }
2710 return true;
2711}
2712
2713bool GLES2DecoderImpl::GenFramebuffersHelper(
2714 GLsizei n, const GLuint* client_ids) {
2715 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352716 if (GetFramebuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032717 return false;
2718 }
2719 }
[email protected]40d90a22013-04-09 03:39:552720 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032721 glGenFramebuffersEXT(n, service_ids.get());
2722 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352723 CreateFramebuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032724 }
2725 return true;
2726}
2727
2728bool GLES2DecoderImpl::GenRenderbuffersHelper(
2729 GLsizei n, const GLuint* client_ids) {
2730 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352731 if (GetRenderbuffer(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032732 return false;
2733 }
2734 }
[email protected]40d90a22013-04-09 03:39:552735 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032736 glGenRenderbuffersEXT(n, service_ids.get());
2737 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352738 CreateRenderbuffer(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032739 }
2740 return true;
2741}
2742
2743bool GLES2DecoderImpl::GenTexturesHelper(GLsizei n, const GLuint* client_ids) {
2744 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352745 if (GetTexture(client_ids[ii])) {
[email protected]ae51d192010-04-27 00:48:032746 return false;
2747 }
2748 }
[email protected]40d90a22013-04-09 03:39:552749 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ae51d192010-04-27 00:48:032750 glGenTextures(n, service_ids.get());
2751 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352752 CreateTexture(client_ids[ii], service_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032753 }
2754 return true;
2755}
2756
2757void GLES2DecoderImpl::DeleteBuffersHelper(
2758 GLsizei n, const GLuint* client_ids) {
2759 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]16ccec12013-02-28 03:40:212760 Buffer* buffer = GetBuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102761 if (buffer && !buffer->IsDeleted()) {
[email protected]e259eb412012-10-13 05:47:242762 state_.vertex_attrib_manager->Unbind(buffer);
[email protected]7cd76fd2013-06-02 21:11:112763 if (state_.bound_array_buffer.get() == buffer) {
[email protected]e259eb412012-10-13 05:47:242764 state_.bound_array_buffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102765 }
[email protected]ed9f9cd2013-02-27 21:12:352766 RemoveBuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032767 }
[email protected]a93bb842010-02-16 23:03:472768 }
[email protected]07f54fcc2009-12-22 02:46:302769}
2770
[email protected]ae51d192010-04-27 00:48:032771void GLES2DecoderImpl::DeleteFramebuffersHelper(
2772 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452773 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152774 features().chromium_framebuffer_multisample;
[email protected]b177ae22011-11-01 03:29:112775
[email protected]a25fa872010-03-25 02:57:582776 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352777 Framebuffer* framebuffer =
2778 GetFramebuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102779 if (framebuffer && !framebuffer->IsDeleted()) {
[email protected]9d3b2e12013-10-02 01:04:342780 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
2781 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]c986af502013-08-14 01:04:442782 framebuffer_state_.clear_state_dirty = true;
[email protected]ebfb73c2012-08-15 02:37:452783 GLenum target = supports_separate_framebuffer_binds ?
2784 GL_DRAW_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112785 glBindFramebufferEXT(target, GetBackbufferServiceId());
2786 }
[email protected]9d3b2e12013-10-02 01:04:342787 if (framebuffer == framebuffer_state_.bound_read_framebuffer.get()) {
2788 framebuffer_state_.bound_read_framebuffer = NULL;
[email protected]ebfb73c2012-08-15 02:37:452789 GLenum target = supports_separate_framebuffer_binds ?
2790 GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
[email protected]b177ae22011-11-01 03:29:112791 glBindFramebufferEXT(target, GetBackbufferServiceId());
[email protected]297ca1c2011-06-20 23:08:462792 }
[email protected]70d34263c2013-01-09 00:27:452793 OnFboChanged();
[email protected]ed9f9cd2013-02-27 21:12:352794 RemoveFramebuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032795 }
[email protected]a25fa872010-03-25 02:57:582796 }
[email protected]07f54fcc2009-12-22 02:46:302797}
2798
[email protected]ae51d192010-04-27 00:48:032799void GLES2DecoderImpl::DeleteRenderbuffersHelper(
2800 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452801 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152802 features().chromium_framebuffer_multisample;
[email protected]a25fa872010-03-25 02:57:582803 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:352804 Renderbuffer* renderbuffer =
2805 GetRenderbuffer(client_ids[ii]);
[email protected]a0b78dc2011-11-11 10:43:102806 if (renderbuffer && !renderbuffer->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:112807 if (state_.bound_renderbuffer.get() == renderbuffer) {
[email protected]e259eb412012-10-13 05:47:242808 state_.bound_renderbuffer = NULL;
[email protected]a0b78dc2011-11-11 10:43:102809 }
2810 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452811 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:342812 if (framebuffer_state_.bound_read_framebuffer.get()) {
2813 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112814 ->UnbindRenderbuffer(GL_READ_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102815 }
[email protected]9d3b2e12013-10-02 01:04:342816 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2817 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112818 ->UnbindRenderbuffer(GL_DRAW_FRAMEBUFFER_EXT, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102819 }
2820 } else {
[email protected]9d3b2e12013-10-02 01:04:342821 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2822 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112823 ->UnbindRenderbuffer(GL_FRAMEBUFFER, renderbuffer);
[email protected]a0b78dc2011-11-11 10:43:102824 }
2825 }
[email protected]c986af502013-08-14 01:04:442826 framebuffer_state_.clear_state_dirty = true;
[email protected]ed9f9cd2013-02-27 21:12:352827 RemoveRenderbuffer(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032828 }
[email protected]a25fa872010-03-25 02:57:582829 }
[email protected]07f54fcc2009-12-22 02:46:302830}
2831
[email protected]ae51d192010-04-27 00:48:032832void GLES2DecoderImpl::DeleteTexturesHelper(
2833 GLsizei n, const GLuint* client_ids) {
[email protected]ebfb73c2012-08-15 02:37:452834 bool supports_separate_framebuffer_binds =
[email protected]62e155e2012-10-23 22:43:152835 features().chromium_framebuffer_multisample;
[email protected]a93bb842010-02-16 23:03:472836 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]370eaf12013-05-18 09:19:492837 TextureRef* texture_ref = GetTexture(client_ids[ii]);
2838 if (texture_ref) {
2839 Texture* texture = texture_ref->texture();
[email protected]a0b78dc2011-11-11 10:43:102840 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:442841 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:462842 }
[email protected]370eaf12013-05-18 09:19:492843 // Unbind texture_ref from texture_ref units.
[email protected]1868a342012-11-07 15:56:022844 for (size_t jj = 0; jj < state_.texture_units.size(); ++jj) {
[email protected]370eaf12013-05-18 09:19:492845 state_.texture_units[jj].Unbind(texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102846 }
2847 // Unbind from current framebuffers.
[email protected]ebfb73c2012-08-15 02:37:452848 if (supports_separate_framebuffer_binds) {
[email protected]9d3b2e12013-10-02 01:04:342849 if (framebuffer_state_.bound_read_framebuffer.get()) {
2850 framebuffer_state_.bound_read_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112851 ->UnbindTexture(GL_READ_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102852 }
[email protected]9d3b2e12013-10-02 01:04:342853 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2854 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112855 ->UnbindTexture(GL_DRAW_FRAMEBUFFER_EXT, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102856 }
2857 } else {
[email protected]9d3b2e12013-10-02 01:04:342858 if (framebuffer_state_.bound_draw_framebuffer.get()) {
2859 framebuffer_state_.bound_draw_framebuffer
[email protected]7cd76fd2013-06-02 21:11:112860 ->UnbindTexture(GL_FRAMEBUFFER, texture_ref);
[email protected]a0b78dc2011-11-11 10:43:102861 }
2862 }
[email protected]e51bdf32011-11-23 22:21:462863#if defined(OS_MACOSX)
[email protected]4f9958142013-07-02 03:58:072864 GLuint service_id = texture->service_id();
[email protected]e51bdf32011-11-23 22:21:462865 if (texture->target() == GL_TEXTURE_RECTANGLE_ARB) {
2866 ReleaseIOSurfaceForTexture(service_id);
2867 }
2868#endif
[email protected]ed9f9cd2013-02-27 21:12:352869 RemoveTexture(client_ids[ii]);
[email protected]ae51d192010-04-27 00:48:032870 }
[email protected]a93bb842010-02-16 23:03:472871 }
[email protected]07f54fcc2009-12-22 02:46:302872}
2873
[email protected]43f28f832010-02-03 02:28:482874// } // anonymous namespace
[email protected]96449d2c2009-11-25 00:01:322875
[email protected]eb54a562010-01-20 21:55:182876bool GLES2DecoderImpl::MakeCurrent() {
[email protected]177d1342013-12-07 04:20:342877 if (!context_.get())
[email protected]63c9b052012-05-17 18:27:382878 return false;
2879
[email protected]177d1342013-12-07 04:20:342880 if (!context_->MakeCurrent(surface_.get()) || WasContextLost()) {
[email protected]38d139d2011-07-14 00:38:432881 LOG(ERROR) << " GLES2DecoderImpl: Context lost during MakeCurrent.";
[email protected]e9f0ca82013-04-01 23:52:292882
2883 // Some D3D drivers cannot recover from device lost in the GPU process
2884 // sandbox. Allow a new GPU process to launch.
2885 if (workarounds().exit_on_context_lost) {
2886 LOG(ERROR) << "Exiting GPU process because some drivers cannot reset"
2887 << " a D3D device in the Chrome GPU process sandbox.";
[email protected]6eb775352013-08-27 05:57:162888#if defined(OS_WIN)
2889 base::win::SetShouldCrashOnProcessDetach(false);
2890#endif
[email protected]e9f0ca82013-04-01 23:52:292891 exit(0);
2892 }
2893
[email protected]63c9b052012-05-17 18:27:382894 return false;
[email protected]38d139d2011-07-14 00:38:432895 }
2896
[email protected]69a8701e2013-03-07 21:31:092897 ProcessFinishedAsyncTransfers();
[email protected]69a8701e2013-03-07 21:31:092898
[email protected]9b753992013-04-27 02:04:412899 // Rebind the FBO if it was unbound by the context.
2900 if (workarounds().unbind_fbo_on_context_switch)
2901 RestoreFramebufferBindings();
2902
[email protected]c986af502013-08-14 01:04:442903 framebuffer_state_.clear_state_dirty = true;
[email protected]370eaf12013-05-18 09:19:492904
[email protected]69a8701e2013-03-07 21:31:092905 return true;
2906}
2907
2908void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
[email protected]5a36dc132013-07-23 23:17:552909 ProcessPendingReadPixels();
[email protected]fe8d73c2013-02-16 22:37:322910 if (engine() && query_manager_.get())
2911 query_manager_->ProcessPendingTransferQueries();
2912
[email protected]5b3a8e02013-03-13 05:36:442913 // TODO(epenner): Is there a better place to do this?
2914 // This needs to occur before we execute any batch of commands
2915 // from the client, as the client may have recieved an async
2916 // completion while issuing those commands.
2917 // "DidFlushStart" would be ideal if we had such a callback.
[email protected]b68b100752013-06-05 08:34:482918 async_pixel_transfer_manager_->BindCompletedAsyncTransfers();
[email protected]eb54a562010-01-20 21:55:182919}
2920
[email protected]a96a6022011-11-04 00:58:122921void GLES2DecoderImpl::ReleaseCurrent() {
2922 if (context_.get())
2923 context_->ReleaseCurrent(surface_.get());
2924}
2925
[email protected]8e3e0662010-08-23 18:46:302926static void RebindCurrentFramebuffer(
2927 GLenum target,
[email protected]4d8f0dd2013-03-09 14:37:062928 Framebuffer* framebuffer,
[email protected]a3783712012-01-20 22:18:242929 GLuint back_buffer_service_id) {
[email protected]4d8f0dd2013-03-09 14:37:062930 GLuint framebuffer_id = framebuffer ? framebuffer->service_id() : 0;
[email protected]297ca1c2011-06-20 23:08:462931
[email protected]a3783712012-01-20 22:18:242932 if (framebuffer_id == 0) {
2933 framebuffer_id = back_buffer_service_id;
[email protected]8e3e0662010-08-23 18:46:302934 }
[email protected]297ca1c2011-06-20 23:08:462935
[email protected]8e3e0662010-08-23 18:46:302936 glBindFramebufferEXT(target, framebuffer_id);
2937}
2938
2939void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
[email protected]c986af502013-08-14 01:04:442940 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:462941
[email protected]62e155e2012-10-23 22:43:152942 if (!features().chromium_framebuffer_multisample) {
[email protected]8e3e0662010-08-23 18:46:302943 RebindCurrentFramebuffer(
2944 GL_FRAMEBUFFER,
[email protected]9d3b2e12013-10-02 01:04:342945 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242946 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302947 } else {
2948 RebindCurrentFramebuffer(
2949 GL_READ_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:342950 framebuffer_state_.bound_read_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242951 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302952 RebindCurrentFramebuffer(
2953 GL_DRAW_FRAMEBUFFER_EXT,
[email protected]9d3b2e12013-10-02 01:04:342954 framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]a3783712012-01-20 22:18:242955 GetBackbufferServiceId());
[email protected]8e3e0662010-08-23 18:46:302956 }
[email protected]70d34263c2013-01-09 00:27:452957 OnFboChanged();
[email protected]8e3e0662010-08-23 18:46:302958}
2959
[email protected]0d6bfdc2011-11-02 01:32:202960bool GLES2DecoderImpl::CheckFramebufferValid(
[email protected]ed9f9cd2013-02-27 21:12:352961 Framebuffer* framebuffer,
[email protected]0d6bfdc2011-11-02 01:32:202962 GLenum target, const char* func_name) {
[email protected]a0b78dc2011-11-11 10:43:102963 if (!framebuffer) {
[email protected]60f22d32012-12-12 00:31:582964 if (backbuffer_needs_clear_bits_) {
2965 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
2966 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
2967 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2968 glClearStencil(0);
2969 glStencilMask(-1);
2970 glClearDepth(1.0f);
2971 glDepthMask(true);
2972 glDisable(GL_SCISSOR_TEST);
2973 glClear(backbuffer_needs_clear_bits_);
2974 backbuffer_needs_clear_bits_ = 0;
2975 RestoreClearState();
2976 }
[email protected]0d6bfdc2011-11-02 01:32:202977 return true;
2978 }
2979
[email protected]968351b2011-12-20 08:26:512980 if (framebuffer_manager()->IsComplete(framebuffer)) {
2981 return true;
2982 }
2983
[email protected]0d6bfdc2011-11-02 01:32:202984 GLenum completeness = framebuffer->IsPossiblyComplete();
2985 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512986 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432987 GL_INVALID_FRAMEBUFFER_OPERATION, func_name, "framebuffer incomplete");
[email protected]3a03a8f2011-03-19 00:51:272988 return false;
2989 }
[email protected]0d6bfdc2011-11-02 01:32:202990
2991 // Are all the attachments cleared?
2992 if (renderbuffer_manager()->HaveUnclearedRenderbuffers() ||
2993 texture_manager()->HaveUnclearedMips()) {
2994 if (!framebuffer->IsCleared()) {
2995 // Can we clear them?
[email protected]73276522012-11-09 05:50:202996 if (framebuffer->GetStatus(texture_manager(), target) !=
2997 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:512998 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:432999 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3000 "framebuffer incomplete (clear)");
[email protected]0d6bfdc2011-11-02 01:32:203001 return false;
3002 }
3003 ClearUnclearedAttachments(target, framebuffer);
3004 }
3005 }
3006
[email protected]968351b2011-12-20 08:26:513007 if (!framebuffer_manager()->IsComplete(framebuffer)) {
[email protected]73276522012-11-09 05:50:203008 if (framebuffer->GetStatus(texture_manager(), target) !=
3009 GL_FRAMEBUFFER_COMPLETE) {
[email protected]ab09b612013-03-11 22:11:513010 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:433011 GL_INVALID_FRAMEBUFFER_OPERATION, func_name,
3012 "framebuffer incomplete (check)");
[email protected]968351b2011-12-20 08:26:513013 return false;
3014 }
3015 framebuffer_manager()->MarkAsComplete(framebuffer);
3016 }
3017
[email protected]0d6bfdc2011-11-02 01:32:203018 // NOTE: At this point we don't know if the framebuffer is complete but
3019 // we DO know that everything that needs to be cleared has been cleared.
[email protected]3a03a8f2011-03-19 00:51:273020 return true;
3021}
3022
[email protected]0d6bfdc2011-11-02 01:32:203023bool GLES2DecoderImpl::CheckBoundFramebuffersValid(const char* func_name) {
[email protected]62e155e2012-10-23 22:43:153024 if (!features().chromium_framebuffer_multisample) {
[email protected]28718a92013-04-04 12:12:513025 bool valid = CheckFramebufferValid(
[email protected]9d3b2e12013-10-02 01:04:343026 framebuffer_state_.bound_draw_framebuffer.get(), GL_FRAMEBUFFER_EXT,
3027 func_name);
[email protected]28718a92013-04-04 12:12:513028
3029 if (valid)
3030 OnUseFramebuffer();
3031
3032 return valid;
[email protected]0d6bfdc2011-11-02 01:32:203033 }
[email protected]9d3b2e12013-10-02 01:04:343034 return CheckFramebufferValid(framebuffer_state_.bound_draw_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113035 GL_DRAW_FRAMEBUFFER_EXT,
3036 func_name) &&
[email protected]9d3b2e12013-10-02 01:04:343037 CheckFramebufferValid(framebuffer_state_.bound_read_framebuffer.get(),
[email protected]7cd76fd2013-06-02 21:11:113038 GL_READ_FRAMEBUFFER_EXT,
3039 func_name);
[email protected]0d6bfdc2011-11-02 01:32:203040}
3041
[email protected]8e3e0662010-08-23 18:46:303042gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
[email protected]ed9f9cd2013-02-27 21:12:353043 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453044 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203045 if (framebuffer != NULL) {
[email protected]ed9f9cd2013-02-27 21:12:353046 const Framebuffer::Attachment* attachment =
[email protected]0d6bfdc2011-11-02 01:32:203047 framebuffer->GetAttachment(GL_COLOR_ATTACHMENT0);
[email protected]9edc6b22010-12-23 02:00:263048 if (attachment) {
3049 return gfx::Size(attachment->width(), attachment->height());
[email protected]246a70452010-03-05 21:53:503050 }
[email protected]9edc6b22010-12-23 02:00:263051 return gfx::Size(0, 0);
[email protected]34ff8b0c2010-10-01 20:06:023052 } else if (offscreen_target_frame_buffer_.get()) {
3053 return offscreen_size_;
[email protected]6217d392010-03-25 22:08:353054 } else {
[email protected]f62a5ab2011-05-23 20:34:153055 return surface_->GetSize();
[email protected]d37231fa2010-04-09 21:16:023056 }
[email protected]246a70452010-03-05 21:53:503057}
3058
[email protected]68586372013-12-11 01:27:593059GLenum GLES2DecoderImpl::GetBoundReadFrameBufferTextureType() {
3060 Framebuffer* framebuffer =
3061 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
3062 if (framebuffer != NULL) {
3063 return framebuffer->GetColorAttachmentTextureType();
3064 } else {
3065 return GL_UNSIGNED_BYTE;
3066 }
3067}
3068
[email protected]9edc6b22010-12-23 02:00:263069GLenum GLES2DecoderImpl::GetBoundReadFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353070 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453071 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203072 if (framebuffer != NULL) {
3073 return framebuffer->GetColorAttachmentFormat();
[email protected]297ca1c2011-06-20 23:08:463074 } else if (offscreen_target_frame_buffer_.get()) {
3075 return offscreen_target_color_format_;
3076 } else {
3077 return back_buffer_color_format_;
3078 }
3079}
3080
3081GLenum GLES2DecoderImpl::GetBoundDrawFrameBufferInternalFormat() {
[email protected]ed9f9cd2013-02-27 21:12:353082 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453083 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203084 if (framebuffer != NULL) {
3085 return framebuffer->GetColorAttachmentFormat();
[email protected]9edc6b22010-12-23 02:00:263086 } else if (offscreen_target_frame_buffer_.get()) {
3087 return offscreen_target_color_format_;
3088 } else {
[email protected]32fe9aa2011-01-21 23:47:133089 return back_buffer_color_format_;
[email protected]9edc6b22010-12-23 02:00:263090 }
3091}
3092
[email protected]9a5afa432011-07-22 18:16:393093void GLES2DecoderImpl::UpdateParentTextureInfo() {
[email protected]2ad674132013-06-05 07:48:513094 if (!offscreen_saved_color_texture_info_.get())
3095 return;
3096 GLenum target = offscreen_saved_color_texture_info_->texture()->target();
3097 glBindTexture(target, offscreen_saved_color_texture_info_->service_id());
3098 texture_manager()->SetLevelInfo(
3099 offscreen_saved_color_texture_info_.get(),
3100 GL_TEXTURE_2D,
3101 0, // level
3102 GL_RGBA,
3103 offscreen_size_.width(),
3104 offscreen_size_.height(),
3105 1, // depth
3106 0, // border
3107 GL_RGBA,
3108 GL_UNSIGNED_BYTE,
3109 true);
3110 texture_manager()->SetParameter(
3111 "UpdateParentTextureInfo",
3112 GetErrorState(),
3113 offscreen_saved_color_texture_info_.get(),
3114 GL_TEXTURE_MAG_FILTER,
3115 GL_NEAREST);
3116 texture_manager()->SetParameter(
3117 "UpdateParentTextureInfo",
3118 GetErrorState(),
3119 offscreen_saved_color_texture_info_.get(),
3120 GL_TEXTURE_MIN_FILTER,
3121 GL_NEAREST);
3122 texture_manager()->SetParameter(
3123 "UpdateParentTextureInfo",
3124 GetErrorState(),
3125 offscreen_saved_color_texture_info_.get(),
3126 GL_TEXTURE_WRAP_S,
3127 GL_CLAMP_TO_EDGE);
3128 texture_manager()->SetParameter(
3129 "UpdateParentTextureInfo",
3130 GetErrorState(),
3131 offscreen_saved_color_texture_info_.get(),
3132 GL_TEXTURE_WRAP_T,
3133 GL_CLAMP_TO_EDGE);
[email protected]c986af502013-08-14 01:04:443134 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
3135 &state_, target);
[email protected]2ad674132013-06-05 07:48:513136 glBindTexture(target, texture_ref ? texture_ref->service_id() : 0);
[email protected]6217d392010-03-25 22:08:353137}
3138
[email protected]799b4b22011-08-22 17:09:593139void GLES2DecoderImpl::SetResizeCallback(
[email protected]729c0b42013-05-26 02:05:073140 const base::Callback<void(gfx::Size, float)>& callback) {
[email protected]9d37f062011-11-22 01:24:523141 resize_callback_ = callback;
[email protected]7ff86b92010-11-25 17:50:003142}
3143
[email protected]1d82e822013-04-10 21:32:323144Logger* GLES2DecoderImpl::GetLogger() {
3145 return &logger_;
[email protected]6b6e7ee2011-12-13 08:04:523146}
3147
[email protected]cac16542014-01-15 17:53:513148void GLES2DecoderImpl::BeginDecoding() {
3149 gpu_tracer_->BeginDecoding();
3150 gpu_trace_commands_ = gpu_tracer_->IsTracing();
3151}
3152
3153void GLES2DecoderImpl::EndDecoding() {
3154 gpu_tracer_->EndDecoding();
3155}
3156
[email protected]d3eba342013-04-18 21:11:503157ErrorState* GLES2DecoderImpl::GetErrorState() {
3158 return state_.GetErrorState();
3159}
3160
[email protected]e3932abb2013-03-13 00:01:373161void GLES2DecoderImpl::SetShaderCacheCallback(
3162 const ShaderCacheCallback& callback) {
3163 shader_cache_callback_ = callback;
3164}
3165
[email protected]840a7e462013-02-27 01:29:513166void GLES2DecoderImpl::SetWaitSyncPointCallback(
3167 const WaitSyncPointCallback& callback) {
3168 wait_sync_point_callback_ = callback;
3169}
3170
[email protected]85a4ac22013-05-31 01:58:473171AsyncPixelTransferManager*
3172 GLES2DecoderImpl::GetAsyncPixelTransferManager() {
3173 return async_pixel_transfer_manager_.get();
3174}
3175
3176void GLES2DecoderImpl::ResetAsyncPixelTransferManagerForTest() {
3177 async_pixel_transfer_manager_.reset();
[email protected]32145a92012-12-17 09:01:593178}
3179
[email protected]498b5c072013-06-04 19:30:073180void GLES2DecoderImpl::SetAsyncPixelTransferManagerForTest(
3181 AsyncPixelTransferManager* manager) {
3182 async_pixel_transfer_manager_ = make_scoped_ptr(manager);
3183}
3184
[email protected]1318e922010-09-17 22:03:163185bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id,
3186 uint32* service_texture_id) {
[email protected]370eaf12013-05-18 09:19:493187 TextureRef* texture_ref = texture_manager()->GetTexture(client_texture_id);
3188 if (texture_ref) {
3189 *service_texture_id = texture_ref->service_id();
[email protected]1318e922010-09-17 22:03:163190 return true;
3191 }
3192 return false;
3193}
3194
[email protected]63b465922012-09-06 02:04:523195uint32 GLES2DecoderImpl::GetTextureUploadCount() {
[email protected]c986af502013-08-14 01:04:443196 return texture_state_.texture_upload_count +
[email protected]b68b100752013-06-05 08:34:483197 async_pixel_transfer_manager_->GetTextureUploadCount();
[email protected]63b465922012-09-06 02:04:523198}
3199
3200base::TimeDelta GLES2DecoderImpl::GetTotalTextureUploadTime() {
[email protected]c986af502013-08-14 01:04:443201 return texture_state_.total_texture_upload_time +
[email protected]b68b100752013-06-05 08:34:483202 async_pixel_transfer_manager_->GetTotalTextureUploadTime();
[email protected]63b465922012-09-06 02:04:523203}
3204
3205base::TimeDelta GLES2DecoderImpl::GetTotalProcessingCommandsTime() {
3206 return total_processing_commands_time_;
3207}
3208
[email protected]dc25dda2012-09-27 21:36:303209void GLES2DecoderImpl::AddProcessingCommandsTime(base::TimeDelta time) {
3210 total_processing_commands_time_ += time;
3211}
3212
[email protected]63c9b052012-05-17 18:27:383213void GLES2DecoderImpl::Destroy(bool have_context) {
[email protected]55e136f2013-04-03 18:50:063214 if (!initialized())
3215 return;
3216
[email protected]63c9b052012-05-17 18:27:383217 DCHECK(!have_context || context_->IsCurrent(NULL));
[email protected]97872062010-11-03 19:07:053218
[email protected]80eb6b52012-01-19 00:14:413219 // Unbind everything.
[email protected]e259eb412012-10-13 05:47:243220 state_.vertex_attrib_manager = NULL;
[email protected]944b62f32012-09-27 02:20:463221 default_vertex_attrib_manager_ = NULL;
[email protected]1868a342012-11-07 15:56:023222 state_.texture_units.clear();
[email protected]e259eb412012-10-13 05:47:243223 state_.bound_array_buffer = NULL;
[email protected]8ebd46c2014-01-08 12:06:133224 state_.current_queries.clear();
[email protected]9d3b2e12013-10-02 01:04:343225 framebuffer_state_.bound_read_framebuffer = NULL;
3226 framebuffer_state_.bound_draw_framebuffer = NULL;
[email protected]e259eb412012-10-13 05:47:243227 state_.bound_renderbuffer = NULL;
[email protected]80eb6b52012-01-19 00:14:413228
[email protected]cadac622013-06-11 16:46:363229 if (offscreen_saved_color_texture_info_.get()) {
[email protected]2ad674132013-06-05 07:48:513230 DCHECK(offscreen_target_color_texture_);
3231 DCHECK_EQ(offscreen_saved_color_texture_info_->service_id(),
3232 offscreen_saved_color_texture_->id());
3233 offscreen_saved_color_texture_->Invalidate();
3234 offscreen_saved_color_texture_info_ = NULL;
3235 }
[email protected]eadc96792010-10-27 19:39:393236 if (have_context) {
[email protected]c322e882012-05-23 18:06:183237 if (copy_texture_CHROMIUM_.get()) {
3238 copy_texture_CHROMIUM_->Destroy();
3239 copy_texture_CHROMIUM_.reset();
3240 }
[email protected]43410e92012-04-20 17:06:283241
[email protected]7cd76fd2013-06-02 21:11:113242 if (state_.current_program.get()) {
3243 program_manager()->UnuseProgram(shader_manager(),
3244 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:143245 }
3246
[email protected]b1122982010-05-17 23:04:243247 if (attrib_0_buffer_id_) {
3248 glDeleteBuffersARB(1, &attrib_0_buffer_id_);
3249 }
[email protected]8fbedc02010-11-18 18:43:403250 if (fixed_attrib_buffer_id_) {
3251 glDeleteBuffersARB(1, &fixed_attrib_buffer_id_);
3252 }
[email protected]b1122982010-05-17 23:04:243253
[email protected]4a4c18b2013-09-13 22:50:103254 if (validation_texture_) {
3255 glDeleteTextures(1, &validation_texture_);
3256 glDeleteFramebuffersEXT(1, &validation_fbo_multisample_);
3257 glDeleteFramebuffersEXT(1, &validation_fbo_);
3258 }
3259
[email protected]97872062010-11-03 19:07:053260 if (offscreen_target_frame_buffer_.get())
[email protected]4bedba72010-04-20 22:08:543261 offscreen_target_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053262 if (offscreen_target_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543263 offscreen_target_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053264 if (offscreen_target_color_render_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023265 offscreen_target_color_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053266 if (offscreen_target_depth_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153267 offscreen_target_depth_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053268 if (offscreen_target_stencil_render_buffer_.get())
[email protected]b9363b22010-06-09 22:06:153269 offscreen_target_stencil_render_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053270 if (offscreen_saved_frame_buffer_.get())
[email protected]34ff8b0c2010-10-01 20:06:023271 offscreen_saved_frame_buffer_->Destroy();
[email protected]97872062010-11-03 19:07:053272 if (offscreen_saved_color_texture_.get())
[email protected]4bedba72010-04-20 22:08:543273 offscreen_saved_color_texture_->Destroy();
[email protected]de26b3c2011-08-03 21:54:273274 if (offscreen_resolved_frame_buffer_.get())
3275 offscreen_resolved_frame_buffer_->Destroy();
3276 if (offscreen_resolved_color_texture_.get())
3277 offscreen_resolved_color_texture_->Destroy();
[email protected]97872062010-11-03 19:07:053278 } else {
3279 if (offscreen_target_frame_buffer_.get())
3280 offscreen_target_frame_buffer_->Invalidate();
3281 if (offscreen_target_color_texture_.get())
3282 offscreen_target_color_texture_->Invalidate();
3283 if (offscreen_target_color_render_buffer_.get())
3284 offscreen_target_color_render_buffer_->Invalidate();
3285 if (offscreen_target_depth_render_buffer_.get())
3286 offscreen_target_depth_render_buffer_->Invalidate();
3287 if (offscreen_target_stencil_render_buffer_.get())
3288 offscreen_target_stencil_render_buffer_->Invalidate();
3289 if (offscreen_saved_frame_buffer_.get())
3290 offscreen_saved_frame_buffer_->Invalidate();
3291 if (offscreen_saved_color_texture_.get())
3292 offscreen_saved_color_texture_->Invalidate();
[email protected]de26b3c2011-08-03 21:54:273293 if (offscreen_resolved_frame_buffer_.get())
3294 offscreen_resolved_frame_buffer_->Invalidate();
3295 if (offscreen_resolved_color_texture_.get())
3296 offscreen_resolved_color_texture_->Invalidate();
[email protected]d37231fa2010-04-09 21:16:023297 }
[email protected]83a52d032013-07-24 10:30:373298
3299 // Current program must be cleared after calling ProgramManager::UnuseProgram.
3300 // Otherwise, we can leak objects. http://crbug.com/258772.
3301 // state_.current_program must be reset before group_ is reset because
3302 // the later deletes the ProgramManager object that referred by
3303 // state_.current_program object.
3304 state_.current_program = NULL;
3305
[email protected]43410e92012-04-20 17:06:283306 copy_texture_CHROMIUM_.reset();
[email protected]97872062010-11-03 19:07:053307
[email protected]882ba1e22012-03-08 19:02:533308 if (query_manager_.get()) {
3309 query_manager_->Destroy(have_context);
3310 query_manager_.reset();
3311 }
3312
[email protected]944b62f32012-09-27 02:20:463313 if (vertex_array_manager_ .get()) {
3314 vertex_array_manager_->Destroy(have_context);
3315 vertex_array_manager_.reset();
3316 }
3317
[email protected]97872062010-11-03 19:07:053318 offscreen_target_frame_buffer_.reset();
3319 offscreen_target_color_texture_.reset();
3320 offscreen_target_color_render_buffer_.reset();
3321 offscreen_target_depth_render_buffer_.reset();
3322 offscreen_target_stencil_render_buffer_.reset();
3323 offscreen_saved_frame_buffer_.reset();
3324 offscreen_saved_color_texture_.reset();
[email protected]de26b3c2011-08-03 21:54:273325 offscreen_resolved_frame_buffer_.reset();
3326 offscreen_resolved_color_texture_.reset();
[email protected]e51bdf32011-11-23 22:21:463327
[email protected]85a4ac22013-05-31 01:58:473328 // Should destroy the transfer manager before the texture manager held
3329 // by the context group.
3330 async_pixel_transfer_manager_.reset();
3331
[email protected]91c94eb2013-10-22 10:32:543332 framebuffer_manager()->RemoveObserver(this);
3333
[email protected]7cd76fd2013-06-02 21:11:113334 if (group_.get()) {
[email protected]2d9d3b92013-01-18 01:07:233335 group_->Destroy(this, have_context);
3336 group_ = NULL;
3337 }
3338
3339 if (context_.get()) {
3340 context_->ReleaseCurrent(NULL);
3341 context_ = NULL;
3342 }
3343
[email protected]e51bdf32011-11-23 22:21:463344#if defined(OS_MACOSX)
3345 for (TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.begin();
3346 it != texture_to_io_surface_map_.end(); ++it) {
3347 CFRelease(it->second);
3348 }
3349 texture_to_io_surface_map_.clear();
3350#endif
[email protected]96449d2c2009-11-25 00:01:323351}
3352
[email protected]63c9b052012-05-17 18:27:383353void GLES2DecoderImpl::SetSurface(
3354 const scoped_refptr<gfx::GLSurface>& surface) {
3355 DCHECK(context_->IsCurrent(NULL));
3356 DCHECK(surface_.get());
3357 surface_ = surface;
3358 RestoreCurrentFramebufferBindings();
3359}
3360
[email protected]2ad674132013-06-05 07:48:513361bool GLES2DecoderImpl::ProduceFrontBuffer(const Mailbox& mailbox) {
[email protected]9a5afa432011-07-22 18:16:393362 if (!offscreen_saved_color_texture_.get())
3363 return false;
[email protected]2ad674132013-06-05 07:48:513364 if (!offscreen_saved_color_texture_info_.get()) {
[email protected]3c644d82011-06-20 19:58:243365 GLuint service_id = offscreen_saved_color_texture_->id();
[email protected]f46476932013-06-08 05:36:073366 offscreen_saved_color_texture_info_ = TextureRef::Create(
3367 texture_manager(), 0, service_id);
[email protected]2ad674132013-06-05 07:48:513368 texture_manager()->SetTarget(offscreen_saved_color_texture_info_.get(),
3369 GL_TEXTURE_2D);
[email protected]9a5afa432011-07-22 18:16:393370 UpdateParentTextureInfo();
[email protected]3c644d82011-06-20 19:58:243371 }
[email protected]2ad674132013-06-05 07:48:513372 gpu::gles2::MailboxName name;
3373 memcpy(name.key, mailbox.name, sizeof(mailbox.name));
3374 return mailbox_manager()->ProduceTexture(
3375 GL_TEXTURE_2D, name, offscreen_saved_color_texture_info_->texture());
[email protected]3c644d82011-06-20 19:58:243376}
3377
[email protected]260ddc4e2012-06-28 00:01:533378size_t GLES2DecoderImpl::GetBackbufferMemoryTotal() {
[email protected]1078f912011-12-23 13:12:143379 size_t total = 0;
3380 if (offscreen_target_frame_buffer_.get()) {
3381 if (offscreen_target_color_texture_.get()) {
3382 total += offscreen_target_color_texture_->estimated_size();
3383 }
3384 if (offscreen_target_color_render_buffer_.get()) {
3385 total += offscreen_target_color_render_buffer_->estimated_size();
3386 }
3387 if (offscreen_target_depth_render_buffer_.get()) {
3388 total += offscreen_target_depth_render_buffer_->estimated_size();
3389 }
3390 if (offscreen_target_stencil_render_buffer_.get()) {
3391 total += offscreen_target_stencil_render_buffer_->estimated_size();
3392 }
3393 if (offscreen_saved_color_texture_.get()) {
3394 total += offscreen_saved_color_texture_->estimated_size();
3395 }
3396 if (offscreen_resolved_color_texture_.get()) {
3397 total += offscreen_resolved_color_texture_->estimated_size();
3398 }
3399 } else {
3400 gfx::Size size = surface_->GetSize();
3401 total += size.width() * size.height() *
3402 GLES2Util::RenderbufferBytesPerPixel(back_buffer_color_format_);
3403 }
[email protected]260ddc4e2012-06-28 00:01:533404 return total;
[email protected]1078f912011-12-23 13:12:143405}
3406
[email protected]799b4b22011-08-22 17:09:593407bool GLES2DecoderImpl::ResizeOffscreenFrameBuffer(const gfx::Size& size) {
3408 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3409 if (!is_offscreen) {
3410 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer called "
3411 << " with an onscreen framebuffer.";
3412 return false;
3413 }
3414
3415 if (offscreen_size_ == size)
3416 return true;
3417
3418 offscreen_size_ = size;
3419 int w = offscreen_size_.width();
3420 int h = offscreen_size_.height();
3421 if (w < 0 || h < 0 || h >= (INT_MAX / 4) / (w ? w : 1)) {
3422 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3423 << "to allocate storage due to excessive dimensions.";
3424 return false;
3425 }
3426
3427 // Reallocate the offscreen target buffers.
3428 DCHECK(offscreen_target_color_format_);
3429 if (IsOffscreenBufferMultisampled()) {
3430 if (!offscreen_target_color_render_buffer_->AllocateStorage(
[email protected]f42f05b2013-11-15 21:46:183431 feature_info_, offscreen_size_, offscreen_target_color_format_,
[email protected]799b4b22011-08-22 17:09:593432 offscreen_target_samples_)) {
3433 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3434 << "to allocate storage for offscreen target color buffer.";
3435 return false;
3436 }
3437 } else {
3438 if (!offscreen_target_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:093439 offscreen_size_, offscreen_target_color_format_, false)) {
[email protected]799b4b22011-08-22 17:09:593440 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3441 << "to allocate storage for offscreen target color texture.";
3442 return false;
3443 }
3444 }
3445 if (offscreen_target_depth_format_ &&
3446 !offscreen_target_depth_render_buffer_->AllocateStorage(
[email protected]f42f05b2013-11-15 21:46:183447 feature_info_, offscreen_size_, offscreen_target_depth_format_,
[email protected]799b4b22011-08-22 17:09:593448 offscreen_target_samples_)) {
3449 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3450 << "to allocate storage for offscreen target depth buffer.";
3451 return false;
3452 }
3453 if (offscreen_target_stencil_format_ &&
3454 !offscreen_target_stencil_render_buffer_->AllocateStorage(
[email protected]f42f05b2013-11-15 21:46:183455 feature_info_, offscreen_size_, offscreen_target_stencil_format_,
[email protected]799b4b22011-08-22 17:09:593456 offscreen_target_samples_)) {
3457 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3458 << "to allocate storage for offscreen target stencil buffer.";
3459 return false;
3460 }
3461
3462 // Attach the offscreen target buffers to the target frame buffer.
3463 if (IsOffscreenBufferMultisampled()) {
3464 offscreen_target_frame_buffer_->AttachRenderBuffer(
3465 GL_COLOR_ATTACHMENT0,
3466 offscreen_target_color_render_buffer_.get());
3467 } else {
3468 offscreen_target_frame_buffer_->AttachRenderTexture(
3469 offscreen_target_color_texture_.get());
3470 }
3471 if (offscreen_target_depth_format_) {
3472 offscreen_target_frame_buffer_->AttachRenderBuffer(
3473 GL_DEPTH_ATTACHMENT,
3474 offscreen_target_depth_render_buffer_.get());
3475 }
3476 const bool packed_depth_stencil =
3477 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3478 if (packed_depth_stencil) {
3479 offscreen_target_frame_buffer_->AttachRenderBuffer(
3480 GL_STENCIL_ATTACHMENT,
3481 offscreen_target_depth_render_buffer_.get());
3482 } else if (offscreen_target_stencil_format_) {
3483 offscreen_target_frame_buffer_->AttachRenderBuffer(
3484 GL_STENCIL_ATTACHMENT,
3485 offscreen_target_stencil_render_buffer_.get());
3486 }
3487
3488 if (offscreen_target_frame_buffer_->CheckStatus() !=
3489 GL_FRAMEBUFFER_COMPLETE) {
3490 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
3491 << "because offscreen FBO was incomplete.";
3492 return false;
3493 }
3494
3495 // Clear the target frame buffer.
3496 {
3497 ScopedFrameBufferBinder binder(this, offscreen_target_frame_buffer_->id());
3498 glClearColor(0, 0, 0, (GLES2Util::GetChannelsForFormat(
3499 offscreen_target_color_format_) & 0x0008) != 0 ? 0 : 1);
3500 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3501 glClearStencil(0);
3502 glStencilMaskSeparate(GL_FRONT, -1);
3503 glStencilMaskSeparate(GL_BACK, -1);
3504 glClearDepth(0);
3505 glDepthMask(GL_TRUE);
3506 glDisable(GL_SCISSOR_TEST);
3507 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3508 RestoreClearState();
3509 }
[email protected]d85ef76d2011-09-08 22:21:433510
3511 // Destroy the offscreen resolved framebuffers.
3512 if (offscreen_resolved_frame_buffer_.get())
3513 offscreen_resolved_frame_buffer_->Destroy();
3514 if (offscreen_resolved_color_texture_.get())
3515 offscreen_resolved_color_texture_->Destroy();
3516 offscreen_resolved_color_texture_.reset();
3517 offscreen_resolved_frame_buffer_.reset();
3518
[email protected]799b4b22011-08-22 17:09:593519 return true;
[email protected]6217d392010-03-25 22:08:353520}
3521
[email protected]799b4b22011-08-22 17:09:593522error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:353523 uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) {
[email protected]09e17272012-11-30 10:30:443524 if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
[email protected]452120872012-09-27 15:21:023525 return error::kDeferCommandUntilLater;
3526
[email protected]799b4b22011-08-22 17:09:593527 GLuint width = static_cast<GLuint>(c.width);
3528 GLuint height = static_cast<GLuint>(c.height);
[email protected]729c0b42013-05-26 02:05:073529 GLfloat scale_factor = c.scale_factor;
[email protected]799b4b22011-08-22 17:09:593530 TRACE_EVENT2("gpu", "glResizeChromium", "width", width, "height", height);
[email protected]d16aa4b2013-02-14 22:35:413531
3532 width = std::max(1U, width);
3533 height = std::max(1U, height);
3534
[email protected]a0d989162011-11-22 13:15:073535#if defined(OS_POSIX) && !defined(OS_MACOSX) && \
3536 !defined(UI_COMPOSITOR_IMAGE_TRANSPORT)
[email protected]7ff86b92010-11-25 17:50:003537 // Make sure that we are done drawing to the back buffer before resizing.
3538 glFinish();
3539#endif
[email protected]799b4b22011-08-22 17:09:593540 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
3541 if (is_offscreen) {
[email protected]7794d512012-04-17 20:36:493542 if (!ResizeOffscreenFrameBuffer(gfx::Size(width, height))) {
3543 LOG(ERROR) << "GLES2DecoderImpl: Context lost because "
3544 << "ResizeOffscreenFrameBuffer failed.";
[email protected]799b4b22011-08-22 17:09:593545 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493546 }
[email protected]7ff86b92010-11-25 17:50:003547 }
[email protected]799b4b22011-08-22 17:09:593548
[email protected]9d37f062011-11-22 01:24:523549 if (!resize_callback_.is_null()) {
[email protected]729c0b42013-05-26 02:05:073550 resize_callback_.Run(gfx::Size(width, height), scale_factor);
[email protected]0e9346b2013-03-16 16:35:443551 DCHECK(context_->IsCurrent(surface_.get()));
[email protected]7794d512012-04-17 20:36:493552 if (!context_->IsCurrent(surface_.get())) {
3553 LOG(ERROR) << "GLES2DecoderImpl: Context lost because context no longer "
3554 << "current after resize callback.";
[email protected]658f7562011-09-09 05:24:053555 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:493556 }
[email protected]658f7562011-09-09 05:24:053557 }
[email protected]799b4b22011-08-22 17:09:593558
3559 return error::kNoError;
[email protected]43ecf372010-11-16 19:19:393560}
3561
[email protected]96449d2c2009-11-25 00:01:323562const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const {
3563 if (command_id > kStartPoint && command_id < kNumCommands) {
3564 return gles2::GetCommandName(static_cast<CommandId>(command_id));
3565 }
3566 return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
3567}
3568
3569// Decode command with its arguments, and call the corresponding GL function.
3570// Note: args is a pointer to the command buffer. As such, it could be changed
3571// by a (malicious) client at any time, so if validation has to happen, it
3572// should operate on a copy of them.
[email protected]f7a64ee2010-02-01 22:24:143573error::Error GLES2DecoderImpl::DoCommand(
[email protected]96449d2c2009-11-25 00:01:323574 unsigned int command,
3575 unsigned int arg_count,
3576 const void* cmd_data) {
[email protected]f7a64ee2010-02-01 22:24:143577 error::Error result = error::kNoError;
[email protected]e844ae22012-01-14 03:36:263578 if (log_commands()) {
[email protected]39ba4f02012-03-26 01:16:003579 // TODO(notme): Change this to a LOG/VLOG that works in release. Tried
[email protected]65f7efe2013-11-28 03:11:473580 // VLOG(1), no luck.
[email protected]1d82e822013-04-10 21:32:323581 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" << "cmd: "
[email protected]d2a0e1a2012-08-12 02:25:013582 << GetCommandName(command);
[email protected]b9849abf2009-11-25 19:13:193583 }
[email protected]96449d2c2009-11-25 00:01:323584 unsigned int command_index = command - kStartPoint - 1;
3585 if (command_index < arraysize(g_command_info)) {
3586 const CommandInfo& info = g_command_info[command_index];
3587 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
3588 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
3589 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
[email protected]cac16542014-01-15 17:53:513590 bool doing_gpu_trace = false;
3591 if (gpu_trace_commands_) {
3592 if (CMD_FLAG_GET_TRACE_LEVEL(info.cmd_flags) <= gpu_trace_level_) {
3593 doing_gpu_trace = true;
3594 gpu_tracer_->Begin(GetCommandName(command), kTraceDecoder);
3595 }
3596 }
3597
[email protected]b9849abf2009-11-25 19:13:193598 uint32 immediate_data_size =
3599 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
[email protected]96449d2c2009-11-25 00:01:323600 switch (command) {
3601 #define GLES2_CMD_OP(name) \
[email protected]ed9f9cd2013-02-27 21:12:353602 case cmds::name::kCmdId: \
[email protected]b9849abf2009-11-25 19:13:193603 result = Handle ## name( \
3604 immediate_data_size, \
[email protected]ed9f9cd2013-02-27 21:12:353605 *static_cast<const gles2::cmds::name*>(cmd_data)); \
[email protected]b9849abf2009-11-25 19:13:193606 break; \
[email protected]96449d2c2009-11-25 00:01:323607
3608 GLES2_COMMAND_LIST(GLES2_CMD_OP)
[email protected]96449d2c2009-11-25 00:01:323609 #undef GLES2_CMD_OP
[email protected]bf0985e2009-12-17 03:04:383610 }
[email protected]cac16542014-01-15 17:53:513611
3612 if (doing_gpu_trace)
3613 gpu_tracer_->End(kTraceDecoder);
3614
[email protected]bf0985e2009-12-17 03:04:383615 if (debug()) {
[email protected]07f54fcc2009-12-22 02:46:303616 GLenum error;
3617 while ((error = glGetError()) != GL_NO_ERROR) {
[email protected]1d82e822013-04-10 21:32:323618 LOG(ERROR) << "[" << logger_.GetLogPrefix() << "] "
[email protected]39ba4f02012-03-26 01:16:003619 << "GL ERROR: " << GLES2Util::GetStringEnum(error) << " : "
3620 << GetCommandName(command);
[email protected]ab09b612013-03-11 22:11:513621 LOCAL_SET_GL_ERROR(error, "DoCommand", "GL error from driver");
[email protected]b9849abf2009-11-25 19:13:193622 }
[email protected]96449d2c2009-11-25 00:01:323623 }
3624 } else {
[email protected]f7a64ee2010-02-01 22:24:143625 result = error::kInvalidArguments;
[email protected]96449d2c2009-11-25 00:01:323626 }
[email protected]b9849abf2009-11-25 19:13:193627 } else {
3628 result = DoCommonCommand(command, arg_count, cmd_data);
[email protected]96449d2c2009-11-25 00:01:323629 }
[email protected]a3a93e7b2010-08-28 00:48:563630 if (result == error::kNoError && current_decoder_error_ != error::kNoError) {
3631 result = current_decoder_error_;
3632 current_decoder_error_ = error::kNoError;
3633 }
[email protected]b9849abf2009-11-25 19:13:193634 return result;
[email protected]96449d2c2009-11-25 00:01:323635}
3636
[email protected]ed9f9cd2013-02-27 21:12:353637void GLES2DecoderImpl::RemoveBuffer(GLuint client_id) {
3638 buffer_manager()->RemoveBuffer(client_id);
[email protected]3916c97e2010-02-25 03:20:503639}
3640
[email protected]ae51d192010-04-27 00:48:033641bool GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353642 if (GetProgram(client_id)) {
[email protected]ae51d192010-04-27 00:48:033643 return false;
3644 }
[email protected]96449d2c2009-11-25 00:01:323645 GLuint service_id = glCreateProgram();
[email protected]ae51d192010-04-27 00:48:033646 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353647 CreateProgram(client_id, service_id);
[email protected]96449d2c2009-11-25 00:01:323648 }
[email protected]ae51d192010-04-27 00:48:033649 return true;
[email protected]96449d2c2009-11-25 00:01:323650}
3651
[email protected]ae51d192010-04-27 00:48:033652bool GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:353653 if (GetShader(client_id)) {
[email protected]ae51d192010-04-27 00:48:033654 return false;
[email protected]96449d2c2009-11-25 00:01:323655 }
[email protected]ae51d192010-04-27 00:48:033656 GLuint service_id = glCreateShader(type);
3657 if (service_id != 0) {
[email protected]ed9f9cd2013-02-27 21:12:353658 CreateShader(client_id, service_id, type);
[email protected]ae51d192010-04-27 00:48:033659 }
3660 return true;
[email protected]96449d2c2009-11-25 00:01:323661}
3662
[email protected]882ba1e22012-03-08 19:02:533663void GLES2DecoderImpl::DoFinish() {
3664 glFinish();
[email protected]5a36dc132013-07-23 23:17:553665 ProcessPendingReadPixels();
[email protected]22e3f552012-03-13 01:54:193666 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533667}
3668
3669void GLES2DecoderImpl::DoFlush() {
3670 glFlush();
[email protected]22e3f552012-03-13 01:54:193671 ProcessPendingQueries();
[email protected]882ba1e22012-03-08 19:02:533672}
3673
[email protected]3916c97e2010-02-25 03:20:503674void GLES2DecoderImpl::DoActiveTexture(GLenum texture_unit) {
[email protected]36cef8ce2010-03-16 07:34:453675 GLuint texture_index = texture_unit - GL_TEXTURE0;
[email protected]1868a342012-11-07 15:56:023676 if (texture_index >= state_.texture_units.size()) {
[email protected]ab09b612013-03-11 22:11:513677 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:533678 "glActiveTexture", texture_unit, "texture_unit");
[email protected]3916c97e2010-02-25 03:20:503679 return;
3680 }
[email protected]e259eb412012-10-13 05:47:243681 state_.active_texture_unit = texture_index;
[email protected]36cef8ce2010-03-16 07:34:453682 glActiveTexture(texture_unit);
[email protected]3916c97e2010-02-25 03:20:503683}
3684
[email protected]051b1372010-04-12 02:42:083685void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint client_id) {
[email protected]b10492f2013-03-08 05:24:073686 Buffer* buffer = NULL;
[email protected]051b1372010-04-12 02:42:083687 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033688 if (client_id != 0) {
[email protected]b10492f2013-03-08 05:24:073689 buffer = GetBuffer(client_id);
3690 if (!buffer) {
[email protected]bf5a8d132011-08-16 08:39:353691 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153692 LOG(ERROR) << "glBindBuffer: id not generated by glGenBuffers";
3693 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353694 return;
3695 }
3696
[email protected]b10492f2013-03-08 05:24:073697 // It's a new id so make a buffer buffer for it.
[email protected]ae51d192010-04-27 00:48:033698 glGenBuffersARB(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353699 CreateBuffer(client_id, service_id);
[email protected]b10492f2013-03-08 05:24:073700 buffer = GetBuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573701 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103702 group_->GetIdAllocator(id_namespaces::kBuffers);
3703 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033704 }
[email protected]051b1372010-04-12 02:42:083705 }
[email protected]b10492f2013-03-08 05:24:073706 LogClientServiceForInfo(buffer, client_id, "glBindBuffer");
3707 if (buffer) {
3708 if (!buffer_manager()->SetTarget(buffer, target)) {
[email protected]ab09b612013-03-11 22:11:513709 LOCAL_SET_GL_ERROR(
3710 GL_INVALID_OPERATION,
3711 "glBindBuffer", "buffer bound to more than 1 target");
[email protected]a93bb842010-02-16 23:03:473712 return;
3713 }
[email protected]b10492f2013-03-08 05:24:073714 service_id = buffer->service_id();
[email protected]a93bb842010-02-16 23:03:473715 }
[email protected]96449d2c2009-11-25 00:01:323716 switch (target) {
3717 case GL_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073718 state_.bound_array_buffer = buffer;
[email protected]96449d2c2009-11-25 00:01:323719 break;
3720 case GL_ELEMENT_ARRAY_BUFFER:
[email protected]b10492f2013-03-08 05:24:073721 state_.vertex_attrib_manager->SetElementArrayBuffer(buffer);
[email protected]96449d2c2009-11-25 00:01:323722 break;
3723 default:
[email protected]a93bb842010-02-16 23:03:473724 NOTREACHED(); // Validation should prevent us getting here.
[email protected]96449d2c2009-11-25 00:01:323725 break;
3726 }
[email protected]051b1372010-04-12 02:42:083727 glBindBuffer(target, service_id);
[email protected]96449d2c2009-11-25 00:01:323728}
3729
[email protected]f3b191b2013-06-19 03:43:543730bool GLES2DecoderImpl::BoundFramebufferHasColorAttachmentWithAlpha(
3731 bool all_draw_buffers) {
3732 Framebuffer* framebuffer =
3733 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
3734 if (!all_draw_buffers || !framebuffer) {
3735 return (GLES2Util::GetChannelsForFormat(
3736 GetBoundDrawFrameBufferInternalFormat()) & 0x0008) != 0;
3737 }
3738 return framebuffer->HasAlphaMRT();
[email protected]297ca1c2011-06-20 23:08:463739}
3740
3741bool GLES2DecoderImpl::BoundFramebufferHasDepthAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353742 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453743 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203744 if (framebuffer) {
3745 return framebuffer->HasDepthAttachment();
[email protected]297ca1c2011-06-20 23:08:463746 }
3747 if (offscreen_target_frame_buffer_.get()) {
3748 return offscreen_target_depth_format_ != 0;
3749 }
3750 return back_buffer_has_depth_;
3751}
3752
3753bool GLES2DecoderImpl::BoundFramebufferHasStencilAttachment() {
[email protected]ed9f9cd2013-02-27 21:12:353754 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:453755 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:203756 if (framebuffer) {
3757 return framebuffer->HasStencilAttachment();
[email protected]297ca1c2011-06-20 23:08:463758 }
3759 if (offscreen_target_frame_buffer_.get()) {
3760 return offscreen_target_stencil_format_ != 0 ||
3761 offscreen_target_depth_format_ == GL_DEPTH24_STENCIL8;
3762 }
3763 return back_buffer_has_stencil_;
3764}
3765
3766void GLES2DecoderImpl::ApplyDirtyState() {
[email protected]c986af502013-08-14 01:04:443767 if (framebuffer_state_.clear_state_dirty) {
[email protected]297ca1c2011-06-20 23:08:463768 glColorMask(
[email protected]e259eb412012-10-13 05:47:243769 state_.color_mask_red, state_.color_mask_green, state_.color_mask_blue,
3770 state_.color_mask_alpha &&
[email protected]f3b191b2013-06-19 03:43:543771 BoundFramebufferHasColorAttachmentWithAlpha(true));
[email protected]297ca1c2011-06-20 23:08:463772 bool have_depth = BoundFramebufferHasDepthAttachment();
[email protected]e259eb412012-10-13 05:47:243773 glDepthMask(state_.depth_mask && have_depth);
[email protected]f731b9462012-10-30 00:35:223774 EnableDisable(GL_DEPTH_TEST, state_.enable_flags.depth_test && have_depth);
[email protected]297ca1c2011-06-20 23:08:463775 bool have_stencil = BoundFramebufferHasStencilAttachment();
[email protected]e259eb412012-10-13 05:47:243776 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423777 GL_FRONT, have_stencil ? state_.stencil_front_writemask : 0);
[email protected]e259eb412012-10-13 05:47:243778 glStencilMaskSeparate(
[email protected]88a61bf2012-10-27 13:00:423779 GL_BACK, have_stencil ? state_.stencil_back_writemask : 0);
[email protected]f731b9462012-10-30 00:35:223780 EnableDisable(
3781 GL_STENCIL_TEST, state_.enable_flags.stencil_test && have_stencil);
3782 EnableDisable(GL_CULL_FACE, state_.enable_flags.cull_face);
3783 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
3784 EnableDisable(GL_BLEND, state_.enable_flags.blend);
[email protected]c986af502013-08-14 01:04:443785 framebuffer_state_.clear_state_dirty = false;
[email protected]297ca1c2011-06-20 23:08:463786 }
3787}
3788
[email protected]1868a342012-11-07 15:56:023789GLuint GLES2DecoderImpl::GetBackbufferServiceId() const {
[email protected]7cd76fd2013-06-02 21:11:113790 return (offscreen_target_frame_buffer_.get())
3791 ? offscreen_target_frame_buffer_->id()
3792 : (surface_.get() ? surface_->GetBackingFrameBufferObject() : 0);
[email protected]1868a342012-11-07 15:56:023793}
3794
3795void GLES2DecoderImpl::RestoreState() const {
[email protected]962bfbe72013-05-24 11:16:143796 TRACE_EVENT1("gpu", "GLES2DecoderImpl::RestoreState",
3797 "context", logger_.GetLogPrefix());
[email protected]29a4d902013-02-26 20:18:063798 // Restore the Framebuffer first because of bugs in Intel drivers.
3799 // Intel drivers incorrectly clip the viewport settings to
3800 // the size of the current framebuffer object.
3801 RestoreFramebufferBindings();
3802 state_.RestoreState();
3803}
3804
3805void GLES2DecoderImpl::RestoreFramebufferBindings() const {
[email protected]9d3b2e12013-10-02 01:04:343806 GLuint service_id =
3807 framebuffer_state_.bound_draw_framebuffer.get()
3808 ? framebuffer_state_.bound_draw_framebuffer->service_id()
3809 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063810 if (!features().chromium_framebuffer_multisample) {
3811 glBindFramebufferEXT(GL_FRAMEBUFFER, service_id);
3812 } else {
3813 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, service_id);
[email protected]9d3b2e12013-10-02 01:04:343814 service_id = framebuffer_state_.bound_read_framebuffer.get()
3815 ? framebuffer_state_.bound_read_framebuffer->service_id()
[email protected]7cd76fd2013-06-02 21:11:113816 : GetBackbufferServiceId();
[email protected]29a4d902013-02-26 20:18:063817 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, service_id);
3818 }
[email protected]70d34263c2013-01-09 00:27:453819 OnFboChanged();
[email protected]29a4d902013-02-26 20:18:063820}
3821
3822void GLES2DecoderImpl::RestoreTextureState(unsigned service_id) const {
[email protected]62e65f02013-05-29 22:28:103823 Texture* texture = texture_manager()->GetTextureForServiceId(service_id);
3824 if (texture) {
[email protected]9bc9a2e82013-04-03 03:56:253825 GLenum target = texture->target();
3826 glBindTexture(target, service_id);
[email protected]29a4d902013-02-26 20:18:063827 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253828 target, GL_TEXTURE_WRAP_S, texture->wrap_s());
[email protected]29a4d902013-02-26 20:18:063829 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253830 target, GL_TEXTURE_WRAP_T, texture->wrap_t());
[email protected]29a4d902013-02-26 20:18:063831 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253832 target, GL_TEXTURE_MIN_FILTER, texture->min_filter());
[email protected]29a4d902013-02-26 20:18:063833 glTexParameteri(
[email protected]9bc9a2e82013-04-03 03:56:253834 target, GL_TEXTURE_MAG_FILTER, texture->mag_filter());
[email protected]29a4d902013-02-26 20:18:063835 RestoreTextureUnitBindings(state_.active_texture_unit);
3836 }
[email protected]70d34263c2013-01-09 00:27:453837}
3838
3839void GLES2DecoderImpl::OnFboChanged() const {
3840 if (workarounds().restore_scissor_on_fbo_change)
[email protected]28718a92013-04-04 12:12:513841 state_.fbo_binding_for_scissor_workaround_dirty_ = true;
3842}
3843
3844// Called after the FBO is checked for completeness.
3845void GLES2DecoderImpl::OnUseFramebuffer() const {
3846 if (state_.fbo_binding_for_scissor_workaround_dirty_) {
3847 state_.fbo_binding_for_scissor_workaround_dirty_ = false;
[email protected]81fc9d02013-03-14 23:53:323848 // The driver forgets the correct scissor when modifying the FBO binding.
[email protected]28718a92013-04-04 12:12:513849 glScissor(state_.scissor_x,
3850 state_.scissor_y,
3851 state_.scissor_width,
3852 state_.scissor_height);
3853
3854 // crbug.com/222018 - Also on QualComm, the flush here avoids flicker,
3855 // it's unclear how this bug works.
3856 glFlush();
3857 }
[email protected]b177ae22011-11-01 03:29:113858}
3859
[email protected]051b1372010-04-12 02:42:083860void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
[email protected]4d8f0dd2013-03-09 14:37:063861 Framebuffer* framebuffer = NULL;
[email protected]051b1372010-04-12 02:42:083862 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033863 if (client_id != 0) {
[email protected]4d8f0dd2013-03-09 14:37:063864 framebuffer = GetFramebuffer(client_id);
3865 if (!framebuffer) {
[email protected]bf5a8d132011-08-16 08:39:353866 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153867 LOG(ERROR)
3868 << "glBindFramebuffer: id not generated by glGenFramebuffers";
3869 current_decoder_error_ = error::kGenericError;
3870 return;
[email protected]bf5a8d132011-08-16 08:39:353871 }
3872
[email protected]4d8f0dd2013-03-09 14:37:063873 // It's a new id so make a framebuffer framebuffer for it.
[email protected]ae51d192010-04-27 00:48:033874 glGenFramebuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353875 CreateFramebuffer(client_id, service_id);
[email protected]4d8f0dd2013-03-09 14:37:063876 framebuffer = GetFramebuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573877 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103878 group_->GetIdAllocator(id_namespaces::kFramebuffers);
3879 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033880 } else {
[email protected]4d8f0dd2013-03-09 14:37:063881 service_id = framebuffer->service_id();
[email protected]051b1372010-04-12 02:42:083882 }
[email protected]4d8f0dd2013-03-09 14:37:063883 framebuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083884 }
[email protected]4d8f0dd2013-03-09 14:37:063885 LogClientServiceForInfo(framebuffer, client_id, "glBindFramebuffer");
[email protected]8e3e0662010-08-23 18:46:303886
3887 if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:343888 framebuffer_state_.bound_draw_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303889 }
[email protected]cac16542014-01-15 17:53:513890
3891 // vmiura: This looks like dup code
[email protected]8e3e0662010-08-23 18:46:303892 if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]9d3b2e12013-10-02 01:04:343893 framebuffer_state_.bound_read_framebuffer = framebuffer;
[email protected]8e3e0662010-08-23 18:46:303894 }
[email protected]6217d392010-03-25 22:08:353895
[email protected]c986af502013-08-14 01:04:443896 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:463897
[email protected]b177ae22011-11-01 03:29:113898 // If we are rendering to the backbuffer get the FBO id for any simulated
3899 // backbuffer.
[email protected]4d8f0dd2013-03-09 14:37:063900 if (framebuffer == NULL) {
[email protected]b177ae22011-11-01 03:29:113901 service_id = GetBackbufferServiceId();
[email protected]297ca1c2011-06-20 23:08:463902 }
[email protected]6217d392010-03-25 22:08:353903
[email protected]051b1372010-04-12 02:42:083904 glBindFramebufferEXT(target, service_id);
[email protected]70d34263c2013-01-09 00:27:453905 OnFboChanged();
[email protected]86093972010-03-11 00:13:563906}
3907
[email protected]051b1372010-04-12 02:42:083908void GLES2DecoderImpl::DoBindRenderbuffer(GLenum target, GLuint client_id) {
[email protected]ee2a79c32013-03-10 03:50:273909 Renderbuffer* renderbuffer = NULL;
[email protected]051b1372010-04-12 02:42:083910 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033911 if (client_id != 0) {
[email protected]ee2a79c32013-03-10 03:50:273912 renderbuffer = GetRenderbuffer(client_id);
3913 if (!renderbuffer) {
[email protected]bf5a8d132011-08-16 08:39:353914 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153915 LOG(ERROR)
3916 << "glBindRenderbuffer: id not generated by glGenRenderbuffers";
3917 current_decoder_error_ = error::kGenericError;
[email protected]bf5a8d132011-08-16 08:39:353918 return;
3919 }
3920
[email protected]ee2a79c32013-03-10 03:50:273921 // It's a new id so make a renderbuffer renderbuffer for it.
[email protected]ae51d192010-04-27 00:48:033922 glGenRenderbuffersEXT(1, &service_id);
[email protected]ed9f9cd2013-02-27 21:12:353923 CreateRenderbuffer(client_id, service_id);
[email protected]ee2a79c32013-03-10 03:50:273924 renderbuffer = GetRenderbuffer(client_id);
[email protected]3b1ecc262011-08-03 22:49:573925 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103926 group_->GetIdAllocator(id_namespaces::kRenderbuffers);
3927 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033928 } else {
[email protected]ee2a79c32013-03-10 03:50:273929 service_id = renderbuffer->service_id();
[email protected]051b1372010-04-12 02:42:083930 }
[email protected]ee2a79c32013-03-10 03:50:273931 renderbuffer->MarkAsValid();
[email protected]051b1372010-04-12 02:42:083932 }
[email protected]ee2a79c32013-03-10 03:50:273933 LogClientServiceForInfo(renderbuffer, client_id, "glBindRenerbuffer");
3934 state_.bound_renderbuffer = renderbuffer;
[email protected]051b1372010-04-12 02:42:083935 glBindRenderbufferEXT(target, service_id);
[email protected]86093972010-03-11 00:13:563936}
3937
[email protected]051b1372010-04-12 02:42:083938void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:493939 TextureRef* texture_ref = NULL;
[email protected]051b1372010-04-12 02:42:083940 GLuint service_id = 0;
[email protected]ae51d192010-04-27 00:48:033941 if (client_id != 0) {
[email protected]370eaf12013-05-18 09:19:493942 texture_ref = GetTexture(client_id);
3943 if (!texture_ref) {
[email protected]bf5a8d132011-08-16 08:39:353944 if (!group_->bind_generates_resource()) {
[email protected]f4eac0702012-03-30 17:55:153945 LOG(ERROR) << "glBindTexture: id not generated by glGenTextures";
3946 current_decoder_error_ = error::kGenericError;
3947 return;
[email protected]bf5a8d132011-08-16 08:39:353948 }
3949
[email protected]02965c22013-03-09 02:40:073950 // It's a new id so make a texture texture for it.
[email protected]ae51d192010-04-27 00:48:033951 glGenTextures(1, &service_id);
[email protected]80eb6b52012-01-19 00:14:413952 DCHECK_NE(0u, service_id);
[email protected]ed9f9cd2013-02-27 21:12:353953 CreateTexture(client_id, service_id);
[email protected]370eaf12013-05-18 09:19:493954 texture_ref = GetTexture(client_id);
[email protected]3b1ecc262011-08-03 22:49:573955 IdAllocatorInterface* id_allocator =
[email protected]066849e32010-05-03 19:14:103956 group_->GetIdAllocator(id_namespaces::kTextures);
3957 id_allocator->MarkAsUsed(client_id);
[email protected]ae51d192010-04-27 00:48:033958 }
3959 } else {
[email protected]370eaf12013-05-18 09:19:493960 texture_ref = texture_manager()->GetDefaultTextureInfo(target);
[email protected]051b1372010-04-12 02:42:083961 }
[email protected]370eaf12013-05-18 09:19:493962 Texture* texture = texture_ref->texture();
[email protected]ae51d192010-04-27 00:48:033963
[email protected]1958e0e2010-04-22 05:17:153964 // Check the texture exists
3965 // Check that we are not trying to bind it to a different target.
[email protected]02965c22013-03-09 02:40:073966 if (texture->target() != 0 && texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:513967 LOCAL_SET_GL_ERROR(
3968 GL_INVALID_OPERATION,
3969 "glBindTexture", "texture bound to more than 1 target.");
[email protected]1958e0e2010-04-22 05:17:153970 return;
3971 }
[email protected]02965c22013-03-09 02:40:073972 if (texture->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:513973 LOCAL_SET_GL_ERROR(
3974 GL_INVALID_OPERATION,
3975 "glBindTexture", "illegal target for stream texture.");
[email protected]b0af4f52011-09-28 22:04:423976 return;
3977 }
[email protected]02965c22013-03-09 02:40:073978 LogClientServiceForInfo(texture, client_id, "glBindTexture");
3979 if (texture->target() == 0) {
[email protected]370eaf12013-05-18 09:19:493980 texture_manager()->SetTarget(texture_ref, target);
[email protected]a93bb842010-02-16 23:03:473981 }
[email protected]02965c22013-03-09 02:40:073982 glBindTexture(target, texture->service_id());
[email protected]32145a92012-12-17 09:01:593983
[email protected]e259eb412012-10-13 05:47:243984 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]3916c97e2010-02-25 03:20:503985 unit.bind_target = target;
[email protected]a93bb842010-02-16 23:03:473986 switch (target) {
3987 case GL_TEXTURE_2D:
[email protected]370eaf12013-05-18 09:19:493988 unit.bound_texture_2d = texture_ref;
[email protected]a93bb842010-02-16 23:03:473989 break;
3990 case GL_TEXTURE_CUBE_MAP:
[email protected]370eaf12013-05-18 09:19:493991 unit.bound_texture_cube_map = texture_ref;
[email protected]a93bb842010-02-16 23:03:473992 break;
[email protected]61eeb33f2011-07-26 15:30:313993 case GL_TEXTURE_EXTERNAL_OES:
[email protected]370eaf12013-05-18 09:19:493994 unit.bound_texture_external_oes = texture_ref;
[email protected]61eeb33f2011-07-26 15:30:313995 break;
[email protected]e51bdf32011-11-23 22:21:463996 case GL_TEXTURE_RECTANGLE_ARB:
[email protected]370eaf12013-05-18 09:19:493997 unit.bound_texture_rectangle_arb = texture_ref;
[email protected]e51bdf32011-11-23 22:21:463998 break;
[email protected]a93bb842010-02-16 23:03:473999 default:
4000 NOTREACHED(); // Validation should prevent us getting here.
4001 break;
4002 }
4003}
4004
[email protected]07f54fcc2009-12-22 02:46:304005void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244006 if (state_.vertex_attrib_manager->Enable(index, false)) {
[email protected]1071e572011-02-09 20:00:124007 if (index != 0 ||
4008 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]b1122982010-05-17 23:04:244009 glDisableVertexAttribArray(index);
4010 }
[email protected]07f54fcc2009-12-22 02:46:304011 } else {
[email protected]ab09b612013-03-11 22:11:514012 LOCAL_SET_GL_ERROR(
4013 GL_INVALID_VALUE,
4014 "glDisableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304015 }
4016}
4017
[email protected]60f22d32012-12-12 00:31:584018void GLES2DecoderImpl::DoDiscardFramebufferEXT(GLenum target,
4019 GLsizei numAttachments,
4020 const GLenum* attachments) {
[email protected]680aa412013-10-31 18:08:014021 if (!features().ext_discard_framebuffer) {
4022 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
4023 "glDiscardFramebufferEXT",
4024 "function not available");
4025 return;
4026 }
4027
[email protected]ed9f9cd2013-02-27 21:12:354028 Framebuffer* framebuffer =
[email protected]60f22d32012-12-12 00:31:584029 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4030
4031 // Validates the attachments. If one of them fails
4032 // the whole command fails.
4033 for (GLsizei i = 0; i < numAttachments; ++i) {
4034 if ((framebuffer &&
4035 !validators_->attachment.IsValid(attachments[i])) ||
4036 (!framebuffer &&
4037 !validators_->backbuffer_attachment.IsValid(attachments[i]))) {
[email protected]ab09b612013-03-11 22:11:514038 LOCAL_SET_GL_ERROR_INVALID_ENUM(
4039 "glDiscardFramebufferEXT", attachments[i], "attachments");
[email protected]60f22d32012-12-12 00:31:584040 return;
4041 }
4042 }
4043
4044 // Marks each one of them as not cleared
4045 for (GLsizei i = 0; i < numAttachments; ++i) {
4046 if (framebuffer) {
4047 framebuffer->MarkAttachmentAsCleared(renderbuffer_manager(),
4048 texture_manager(),
4049 attachments[i],
4050 false);
4051 } else {
4052 switch (attachments[i]) {
4053 case GL_COLOR_EXT:
4054 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
4055 break;
4056 case GL_DEPTH_EXT:
4057 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
4058 case GL_STENCIL_EXT:
4059 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
4060 break;
4061 default:
4062 NOTREACHED();
4063 break;
4064 }
4065 }
4066 }
4067
[email protected]d49c5402013-09-11 15:39:024068 // If the default framebuffer is bound but we are still rendering to an
4069 // FBO, translate attachment names that refer to default framebuffer
4070 // channels to corresponding framebuffer attachments.
4071 scoped_ptr<GLenum[]> translated_attachments(new GLenum[numAttachments]);
4072 for (GLsizei i = 0; i < numAttachments; ++i) {
4073 GLenum attachment = attachments[i];
4074 if (!framebuffer && GetBackbufferServiceId()) {
4075 switch (attachment) {
4076 case GL_COLOR_EXT:
4077 attachment = GL_COLOR_ATTACHMENT0;
4078 break;
4079 case GL_DEPTH_EXT:
4080 attachment = GL_DEPTH_ATTACHMENT;
4081 break;
4082 case GL_STENCIL_EXT:
4083 attachment = GL_STENCIL_ATTACHMENT;
4084 break;
4085 default:
4086 NOTREACHED();
4087 return;
4088 }
4089 }
4090 translated_attachments[i] = attachment;
4091 }
4092
4093 glDiscardFramebufferEXT(target, numAttachments, translated_attachments.get());
[email protected]60f22d32012-12-12 00:31:584094}
4095
[email protected]07f54fcc2009-12-22 02:46:304096void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
[email protected]e259eb412012-10-13 05:47:244097 if (state_.vertex_attrib_manager->Enable(index, true)) {
[email protected]07f54fcc2009-12-22 02:46:304098 glEnableVertexAttribArray(index);
4099 } else {
[email protected]ab09b612013-03-11 22:11:514100 LOCAL_SET_GL_ERROR(
4101 GL_INVALID_VALUE, "glEnableVertexAttribArray", "index out of range");
[email protected]07f54fcc2009-12-22 02:46:304102 }
4103}
4104
[email protected]a93bb842010-02-16 23:03:474105void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
[email protected]c986af502013-08-14 01:04:444106 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
4107 &state_, target);
[email protected]370eaf12013-05-18 09:19:494108 if (!texture_ref ||
4109 !texture_manager()->CanGenerateMipmaps(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:514110 LOCAL_SET_GL_ERROR(
4111 GL_INVALID_OPERATION, "glGenerateMipmap", "Can not generate mips");
[email protected]a93bb842010-02-16 23:03:474112 return;
4113 }
[email protected]38c0a972012-05-12 00:48:024114
[email protected]12d95352012-12-14 07:23:544115 if (target == GL_TEXTURE_CUBE_MAP) {
4116 for (int i = 0; i < 6; ++i) {
4117 GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i;
[email protected]370eaf12013-05-18 09:19:494118 if (!texture_manager()->ClearTextureLevel(this, texture_ref, face, 0)) {
[email protected]ab09b612013-03-11 22:11:514119 LOCAL_SET_GL_ERROR(
4120 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544121 return;
4122 }
4123 }
4124 } else {
[email protected]370eaf12013-05-18 09:19:494125 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, 0)) {
[email protected]ab09b612013-03-11 22:11:514126 LOCAL_SET_GL_ERROR(
4127 GL_OUT_OF_MEMORY, "glGenerateMipmap", "dimensions too big");
[email protected]12d95352012-12-14 07:23:544128 return;
4129 }
[email protected]7687479c2012-05-14 23:54:044130 }
4131
[email protected]ab09b612013-03-11 22:11:514132 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glGenerateMipmap");
[email protected]59f3ca02011-03-26 22:24:194133 // Workaround for Mac driver bug. In the large scheme of things setting
4134 // glTexParamter twice for glGenerateMipmap is probably not a lage performance
[email protected]a8bad262011-10-21 18:28:564135 // hit so there's probably no need to make this conditional. The bug appears
4136 // to be that if the filtering mode is set to something that doesn't require
4137 // mipmaps for rendering, or is never set to something other than the default,
4138 // then glGenerateMipmap misbehaves.
[email protected]62e155e2012-10-23 22:43:154139 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]c892a4e12012-05-08 18:20:194140 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
4141 }
[email protected]a93bb842010-02-16 23:03:474142 glGenerateMipmapEXT(target);
[email protected]62e155e2012-10-23 22:43:154143 if (workarounds().set_texture_filter_before_generating_mipmap) {
[email protected]370eaf12013-05-18 09:19:494144 glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
4145 texture_ref->texture()->min_filter());
[email protected]c892a4e12012-05-08 18:20:194146 }
[email protected]ab09b612013-03-11 22:11:514147 GLenum error = LOCAL_PEEK_GL_ERROR("glGenerateMipmap");
[email protected]38c0a972012-05-12 00:48:024148 if (error == GL_NO_ERROR) {
[email protected]370eaf12013-05-18 09:19:494149 texture_manager()->MarkMipmapsGenerated(texture_ref);
[email protected]38c0a972012-05-12 00:48:024150 }
[email protected]a93bb842010-02-16 23:03:474151}
4152
[email protected]b273e432010-04-12 17:23:584153bool GLES2DecoderImpl::GetHelper(
4154 GLenum pname, GLint* params, GLsizei* num_written) {
[email protected]b273e432010-04-12 17:23:584155 DCHECK(num_written);
[email protected]b9363b22010-06-09 22:06:154156 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
4157 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:434158 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
4159 *num_written = 1;
4160 if (params) {
[email protected]68586372013-12-11 01:27:594161 *params = GLES2Util::GetPreferredGLReadPixelsFormat(
4162 GetBoundReadFrameBufferInternalFormat());
[email protected]ad84a3a2012-06-08 21:42:434163 }
4164 return true;
4165 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
4166 *num_written = 1;
4167 if (params) {
[email protected]68586372013-12-11 01:27:594168 *params = GLES2Util::GetPreferredGLReadPixelsType(
4169 GetBoundReadFrameBufferInternalFormat(),
4170 GetBoundReadFrameBufferTextureType());
[email protected]ad84a3a2012-06-08 21:42:434171 }
4172 return true;
4173 case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
4174 *num_written = 1;
4175 if (params) {
4176 *params = group_->max_fragment_uniform_vectors();
4177 }
4178 return true;
4179 case GL_MAX_VARYING_VECTORS:
4180 *num_written = 1;
4181 if (params) {
4182 *params = group_->max_varying_vectors();
4183 }
4184 return true;
4185 case GL_MAX_VERTEX_UNIFORM_VECTORS:
4186 *num_written = 1;
4187 if (params) {
4188 *params = group_->max_vertex_uniform_vectors();
4189 }
4190 return true;
[email protected]4e8a5b122010-05-08 22:00:104191 }
[email protected]5cb735d2011-10-13 01:37:234192 }
4193 switch (pname) {
[email protected]5094b0f2010-11-09 19:45:244194 case GL_MAX_VIEWPORT_DIMS:
4195 if (offscreen_target_frame_buffer_.get()) {
4196 *num_written = 2;
4197 if (params) {
4198 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4199 params[1] = renderbuffer_manager()->max_renderbuffer_size();
4200 }
4201 return true;
4202 }
[email protected]5cb735d2011-10-13 01:37:234203 return false;
[email protected]84afefa2011-10-19 21:45:534204 case GL_MAX_SAMPLES:
4205 *num_written = 1;
4206 if (params) {
4207 params[0] = renderbuffer_manager()->max_samples();
4208 }
4209 return true;
4210 case GL_MAX_RENDERBUFFER_SIZE:
4211 *num_written = 1;
4212 if (params) {
4213 params[0] = renderbuffer_manager()->max_renderbuffer_size();
4214 }
4215 return true;
[email protected]5cb735d2011-10-13 01:37:234216 case GL_MAX_TEXTURE_SIZE:
4217 *num_written = 1;
4218 if (params) {
4219 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_2D);
4220 }
4221 return true;
4222 case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
4223 *num_written = 1;
4224 if (params) {
4225 params[0] = texture_manager()->MaxSizeForTarget(GL_TEXTURE_CUBE_MAP);
4226 }
4227 return true;
[email protected]2f143d482013-03-14 18:04:494228 case GL_MAX_COLOR_ATTACHMENTS_EXT:
4229 *num_written = 1;
4230 if (params) {
4231 params[0] = group_->max_color_attachments();
4232 }
4233 return true;
4234 case GL_MAX_DRAW_BUFFERS_ARB:
4235 *num_written = 1;
4236 if (params) {
4237 params[0] = group_->max_draw_buffers();
4238 }
4239 return true;
[email protected]297ca1c2011-06-20 23:08:464240 case GL_ALPHA_BITS:
4241 *num_written = 1;
4242 if (params) {
4243 GLint v = 0;
4244 glGetIntegerv(GL_ALPHA_BITS, &v);
[email protected]f3b191b2013-06-19 03:43:544245 params[0] = BoundFramebufferHasColorAttachmentWithAlpha(false) ? v : 0;
[email protected]297ca1c2011-06-20 23:08:464246 }
4247 return true;
4248 case GL_DEPTH_BITS:
4249 *num_written = 1;
4250 if (params) {
4251 GLint v = 0;
4252 glGetIntegerv(GL_DEPTH_BITS, &v);
4253 params[0] = BoundFramebufferHasDepthAttachment() ? v : 0;
4254 }
4255 return true;
4256 case GL_STENCIL_BITS:
4257 *num_written = 1;
4258 if (params) {
4259 GLint v = 0;
4260 glGetIntegerv(GL_STENCIL_BITS, &v);
4261 params[0] = BoundFramebufferHasStencilAttachment() ? v : 0;
4262 }
4263 return true;
[email protected]656dcaad2010-05-07 17:18:374264 case GL_COMPRESSED_TEXTURE_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114265 *num_written = validators_->compressed_texture_format.GetValues().size();
4266 if (params) {
4267 for (GLint ii = 0; ii < *num_written; ++ii) {
4268 params[ii] = validators_->compressed_texture_format.GetValues()[ii];
4269 }
4270 }
[email protected]656dcaad2010-05-07 17:18:374271 return true;
[email protected]b273e432010-04-12 17:23:584272 case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
4273 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104274 if (params) {
[email protected]302ce6d2011-07-07 23:28:114275 *params = validators_->compressed_texture_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104276 }
[email protected]b273e432010-04-12 17:23:584277 return true;
4278 case GL_NUM_SHADER_BINARY_FORMATS:
4279 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104280 if (params) {
[email protected]302ce6d2011-07-07 23:28:114281 *params = validators_->shader_binary_format.GetValues().size();
[email protected]4e8a5b122010-05-08 22:00:104282 }
[email protected]b273e432010-04-12 17:23:584283 return true;
4284 case GL_SHADER_BINARY_FORMATS:
[email protected]302ce6d2011-07-07 23:28:114285 *num_written = validators_->shader_binary_format.GetValues().size();
4286 if (params) {
4287 for (GLint ii = 0; ii < *num_written; ++ii) {
4288 params[ii] = validators_->shader_binary_format.GetValues()[ii];
4289 }
4290 }
4291 return true;
[email protected]b273e432010-04-12 17:23:584292 case GL_SHADER_COMPILER:
4293 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104294 if (params) {
4295 *params = GL_TRUE;
4296 }
[email protected]b273e432010-04-12 17:23:584297 return true;
[email protected]6b8cf1a2010-05-06 16:13:584298 case GL_ARRAY_BUFFER_BINDING:
4299 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104300 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114301 if (state_.bound_array_buffer.get()) {
[email protected]4e8a5b122010-05-08 22:00:104302 GLuint client_id = 0;
[email protected]e259eb412012-10-13 05:47:244303 buffer_manager()->GetClientId(state_.bound_array_buffer->service_id(),
[email protected]4e8a5b122010-05-08 22:00:104304 &client_id);
4305 *params = client_id;
4306 } else {
4307 *params = 0;
4308 }
[email protected]6b8cf1a2010-05-06 16:13:584309 }
4310 return true;
4311 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
4312 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104313 if (params) {
[email protected]e259eb412012-10-13 05:47:244314 if (state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]4e8a5b122010-05-08 22:00:104315 GLuint client_id = 0;
4316 buffer_manager()->GetClientId(
[email protected]b04e24c2013-01-08 18:35:254317 state_.vertex_attrib_manager->element_array_buffer()->
4318 service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104319 *params = client_id;
4320 } else {
4321 *params = 0;
4322 }
[email protected]6b8cf1a2010-05-06 16:13:584323 }
4324 return true;
4325 case GL_FRAMEBUFFER_BINDING:
[email protected]8e3e0662010-08-23 18:46:304326 // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
[email protected]6b8cf1a2010-05-06 16:13:584327 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104328 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354329 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454330 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
[email protected]0d6bfdc2011-11-02 01:32:204331 if (framebuffer) {
[email protected]4e8a5b122010-05-08 22:00:104332 GLuint client_id = 0;
4333 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204334 framebuffer->service_id(), &client_id);
[email protected]8e3e0662010-08-23 18:46:304335 *params = client_id;
4336 } else {
4337 *params = 0;
4338 }
4339 }
4340 return true;
[email protected]ebfb73c2012-08-15 02:37:454341 case GL_READ_FRAMEBUFFER_BINDING_EXT:
[email protected]8e3e0662010-08-23 18:46:304342 *num_written = 1;
4343 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354344 Framebuffer* framebuffer =
[email protected]ebfb73c2012-08-15 02:37:454345 GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER_EXT);
[email protected]0d6bfdc2011-11-02 01:32:204346 if (framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304347 GLuint client_id = 0;
4348 framebuffer_manager()->GetClientId(
[email protected]0d6bfdc2011-11-02 01:32:204349 framebuffer->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104350 *params = client_id;
4351 } else {
4352 *params = 0;
4353 }
[email protected]6b8cf1a2010-05-06 16:13:584354 }
4355 return true;
4356 case GL_RENDERBUFFER_BINDING:
4357 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104358 if (params) {
[email protected]ed9f9cd2013-02-27 21:12:354359 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:204360 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
4361 if (renderbuffer) {
[email protected]62e65f02013-05-29 22:28:104362 *params = renderbuffer->client_id();
[email protected]4e8a5b122010-05-08 22:00:104363 } else {
4364 *params = 0;
4365 }
[email protected]6b8cf1a2010-05-06 16:13:584366 }
4367 return true;
4368 case GL_CURRENT_PROGRAM:
4369 *num_written = 1;
[email protected]4e8a5b122010-05-08 22:00:104370 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114371 if (state_.current_program.get()) {
[email protected]4e8a5b122010-05-08 22:00:104372 GLuint client_id = 0;
4373 program_manager()->GetClientId(
[email protected]e259eb412012-10-13 05:47:244374 state_.current_program->service_id(), &client_id);
[email protected]4e8a5b122010-05-08 22:00:104375 *params = client_id;
4376 } else {
4377 *params = 0;
4378 }
[email protected]6b8cf1a2010-05-06 16:13:584379 }
4380 return true;
[email protected]bf835842012-11-19 15:21:514381 case GL_VERTEX_ARRAY_BINDING_OES:
4382 *num_written = 1;
4383 if (params) {
[email protected]7cd76fd2013-06-02 21:11:114384 if (state_.vertex_attrib_manager.get() !=
4385 default_vertex_attrib_manager_.get()) {
[email protected]bf835842012-11-19 15:21:514386 GLuint client_id = 0;
4387 vertex_array_manager_->GetClientId(
4388 state_.vertex_attrib_manager->service_id(), &client_id);
4389 *params = client_id;
4390 } else {
4391 *params = 0;
4392 }
4393 }
4394 return true;
[email protected]4e8a5b122010-05-08 22:00:104395 case GL_TEXTURE_BINDING_2D:
4396 *num_written = 1;
4397 if (params) {
[email protected]e259eb412012-10-13 05:47:244398 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114399 if (unit.bound_texture_2d.get()) {
[email protected]62e65f02013-05-29 22:28:104400 *params = unit.bound_texture_2d->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584401 } else {
4402 *params = 0;
4403 }
[email protected]6b8cf1a2010-05-06 16:13:584404 }
[email protected]4e8a5b122010-05-08 22:00:104405 return true;
4406 case GL_TEXTURE_BINDING_CUBE_MAP:
4407 *num_written = 1;
4408 if (params) {
[email protected]e259eb412012-10-13 05:47:244409 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114410 if (unit.bound_texture_cube_map.get()) {
[email protected]62e65f02013-05-29 22:28:104411 *params = unit.bound_texture_cube_map->client_id();
[email protected]6b8cf1a2010-05-06 16:13:584412 } else {
4413 *params = 0;
4414 }
[email protected]6b8cf1a2010-05-06 16:13:584415 }
[email protected]4e8a5b122010-05-08 22:00:104416 return true;
[email protected]61eeb33f2011-07-26 15:30:314417 case GL_TEXTURE_BINDING_EXTERNAL_OES:
4418 *num_written = 1;
4419 if (params) {
[email protected]e259eb412012-10-13 05:47:244420 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114421 if (unit.bound_texture_external_oes.get()) {
[email protected]62e65f02013-05-29 22:28:104422 *params = unit.bound_texture_external_oes->client_id();
[email protected]61eeb33f2011-07-26 15:30:314423 } else {
4424 *params = 0;
4425 }
4426 }
4427 return true;
[email protected]e51bdf32011-11-23 22:21:464428 case GL_TEXTURE_BINDING_RECTANGLE_ARB:
4429 *num_written = 1;
4430 if (params) {
[email protected]e259eb412012-10-13 05:47:244431 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
[email protected]7cd76fd2013-06-02 21:11:114432 if (unit.bound_texture_rectangle_arb.get()) {
[email protected]62e65f02013-05-29 22:28:104433 *params = unit.bound_texture_rectangle_arb->client_id();
[email protected]e51bdf32011-11-23 22:21:464434 } else {
4435 *params = 0;
4436 }
4437 }
4438 return true;
[email protected]6c75c712012-06-19 15:43:174439 case GL_UNPACK_FLIP_Y_CHROMIUM:
4440 *num_written = 1;
4441 if (params) {
4442 params[0] = unpack_flip_y_;
4443 }
4444 return true;
4445 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
4446 *num_written = 1;
4447 if (params) {
4448 params[0] = unpack_premultiply_alpha_;
4449 }
4450 return true;
4451 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
4452 *num_written = 1;
4453 if (params) {
4454 params[0] = unpack_unpremultiply_alpha_;
4455 }
4456 return true;
[email protected]b273e432010-04-12 17:23:584457 default:
[email protected]2f143d482013-03-14 18:04:494458 if (pname >= GL_DRAW_BUFFER0_ARB &&
4459 pname < GL_DRAW_BUFFER0_ARB + group_->max_draw_buffers()) {
4460 *num_written = 1;
4461 if (params) {
4462 Framebuffer* framebuffer =
4463 GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
4464 if (framebuffer) {
4465 params[0] = framebuffer->GetDrawBuffer(pname);
4466 } else { // backbuffer
4467 if (pname == GL_DRAW_BUFFER0_ARB)
4468 params[0] = group_->draw_buffer();
4469 else
4470 params[0] = GL_NONE;
4471 }
4472 }
4473 return true;
4474 }
[email protected]4e8a5b122010-05-08 22:00:104475 *num_written = util_.GLGetNumValuesReturned(pname);
[email protected]c5d798342010-09-24 20:42:534476 return false;
[email protected]b273e432010-04-12 17:23:584477 }
4478}
4479
[email protected]4e8a5b122010-05-08 22:00:104480bool GLES2DecoderImpl::GetNumValuesReturnedForGLGet(
4481 GLenum pname, GLsizei* num_values) {
[email protected]d058bca2012-11-26 10:27:264482 if (state_.GetStateAsGLint(pname, NULL, num_values)) {
[email protected]f63b1232012-10-31 07:03:534483 return true;
4484 }
[email protected]4e8a5b122010-05-08 22:00:104485 return GetHelper(pname, NULL, num_values);
4486}
4487
[email protected]7d3c36e2013-07-12 14:13:164488GLenum GLES2DecoderImpl::AdjustGetPname(GLenum pname) {
4489 if (GL_MAX_SAMPLES == pname &&
4490 features().use_img_for_multisampled_render_to_texture) {
4491 return GL_MAX_SAMPLES_IMG;
4492 }
4493 return pname;
4494}
4495
[email protected]b273e432010-04-12 17:23:584496void GLES2DecoderImpl::DoGetBooleanv(GLenum pname, GLboolean* params) {
4497 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104498 GLsizei num_written = 0;
[email protected]f63b1232012-10-31 07:03:534499 if (GetNumValuesReturnedForGLGet(pname, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554500 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]d058bca2012-11-26 10:27:264501 if (!state_.GetStateAsGLint(pname, values.get(), &num_written)) {
[email protected]f63b1232012-10-31 07:03:534502 GetHelper(pname, values.get(), &num_written);
4503 }
[email protected]b273e432010-04-12 17:23:584504 for (GLsizei ii = 0; ii < num_written; ++ii) {
4505 params[ii] = static_cast<GLboolean>(values[ii]);
4506 }
4507 } else {
[email protected]7d3c36e2013-07-12 14:13:164508 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584509 glGetBooleanv(pname, params);
4510 }
4511}
4512
4513void GLES2DecoderImpl::DoGetFloatv(GLenum pname, GLfloat* params) {
4514 DCHECK(params);
[email protected]4e8a5b122010-05-08 22:00:104515 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:264516 if (!state_.GetStateAsGLfloat(pname, params, &num_written)) {
[email protected]f63b1232012-10-31 07:03:534517 if (GetHelper(pname, NULL, &num_written)) {
[email protected]40d90a22013-04-09 03:39:554518 scoped_ptr<GLint[]> values(new GLint[num_written]);
[email protected]f63b1232012-10-31 07:03:534519 GetHelper(pname, values.get(), &num_written);
4520 for (GLsizei ii = 0; ii < num_written; ++ii) {
4521 params[ii] = static_cast<GLfloat>(values[ii]);
4522 }
4523 } else {
[email protected]7d3c36e2013-07-12 14:13:164524 pname = AdjustGetPname(pname);
[email protected]f63b1232012-10-31 07:03:534525 glGetFloatv(pname, params);
[email protected]b273e432010-04-12 17:23:584526 }
[email protected]b273e432010-04-12 17:23:584527 }
4528}
4529
4530void GLES2DecoderImpl::DoGetIntegerv(GLenum pname, GLint* params) {
4531 DCHECK(params);
4532 GLsizei num_written;
[email protected]d058bca2012-11-26 10:27:264533 if (!state_.GetStateAsGLint(pname, params, &num_written) &&
[email protected]f63b1232012-10-31 07:03:534534 !GetHelper(pname, params, &num_written)) {
[email protected]7d3c36e2013-07-12 14:13:164535 pname = AdjustGetPname(pname);
[email protected]b273e432010-04-12 17:23:584536 glGetIntegerv(pname, params);
4537 }
4538}
4539
[email protected]a0c3e972010-04-21 00:49:134540void GLES2DecoderImpl::DoGetProgramiv(
4541 GLuint program_id, GLenum pname, GLint* params) {
[email protected]df37b9932013-03-08 05:21:424542 Program* program = GetProgramInfoNotShader(program_id, "glGetProgramiv");
4543 if (!program) {
[email protected]a0c3e972010-04-21 00:49:134544 return;
4545 }
[email protected]df37b9932013-03-08 05:21:424546 program->GetProgramiv(pname, params);
[email protected]a0c3e972010-04-21 00:49:134547}
4548
[email protected]17cfbe0e2013-03-07 01:26:084549void GLES2DecoderImpl::DoGetBufferParameteriv(
4550 GLenum target, GLenum pname, GLint* params) {
[email protected]0fbba3732013-07-17 15:40:134551 // Just delegate it. Some validation is actually done before this.
4552 buffer_manager()->ValidateAndDoGetBufferParameteriv(
4553 &state_, target, pname, params);
[email protected]17cfbe0e2013-03-07 01:26:084554}
4555
[email protected]258a3313f2011-10-18 20:13:574556void GLES2DecoderImpl::DoBindAttribLocation(
[email protected]df37b9932013-03-08 05:21:424557 GLuint program_id, GLuint index, const char* name) {
[email protected]258a3313f2011-10-18 20:13:574558 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514559 LOCAL_SET_GL_ERROR(
4560 GL_INVALID_VALUE, "glBindAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:574561 return;
4562 }
[email protected]68dcb1f2012-04-07 00:14:564563 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514564 LOCAL_SET_GL_ERROR(
4565 GL_INVALID_OPERATION, "glBindAttribLocation", "reserved prefix");
[email protected]68dcb1f2012-04-07 00:14:564566 return;
4567 }
4568 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:514569 LOCAL_SET_GL_ERROR(
4570 GL_INVALID_VALUE, "glBindAttribLocation", "index out of range");
[email protected]68dcb1f2012-04-07 00:14:564571 return;
4572 }
[email protected]df37b9932013-03-08 05:21:424573 Program* program = GetProgramInfoNotShader(
4574 program_id, "glBindAttribLocation");
4575 if (!program) {
[email protected]258a3313f2011-10-18 20:13:574576 return;
[email protected]558847a2010-03-24 07:02:544577 }
[email protected]df37b9932013-03-08 05:21:424578 program->SetAttribLocationBinding(name, static_cast<GLint>(index));
4579 glBindAttribLocation(program->service_id(), index, name);
[email protected]258a3313f2011-10-18 20:13:574580}
4581
4582error::Error GLES2DecoderImpl::HandleBindAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:354583 uint32 immediate_data_size, const cmds::BindAttribLocation& c) {
[email protected]258a3313f2011-10-18 20:13:574584 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544585 GLuint index = static_cast<GLuint>(c.index);
4586 uint32 name_size = c.data_size;
4587 const char* name = GetSharedMemoryAs<const char*>(
4588 c.name_shm_id, c.name_shm_offset, name_size);
4589 if (name == NULL) {
4590 return error::kOutOfBounds;
4591 }
4592 String name_str(name, name_size);
[email protected]258a3313f2011-10-18 20:13:574593 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544594 return error::kNoError;
4595}
4596
[email protected]558847a2010-03-24 07:02:544597error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:354598 uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) {
[email protected]6b8cf1a2010-05-06 16:13:584599 GLuint program = static_cast<GLuint>(c.program);
[email protected]558847a2010-03-24 07:02:544600 GLuint index = static_cast<GLuint>(c.index);
4601 Bucket* bucket = GetBucket(c.name_bucket_id);
4602 if (!bucket || bucket->size() == 0) {
4603 return error::kInvalidArguments;
4604 }
4605 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:184606 if (!bucket->GetAsString(&name_str)) {
4607 return error::kInvalidArguments;
4608 }
[email protected]258a3313f2011-10-18 20:13:574609 DoBindAttribLocation(program, index, name_str.c_str());
[email protected]558847a2010-03-24 07:02:544610 return error::kNoError;
4611}
4612
[email protected]2be6abf32012-06-26 00:28:334613void GLES2DecoderImpl::DoBindUniformLocationCHROMIUM(
[email protected]df37b9932013-03-08 05:21:424614 GLuint program_id, GLint location, const char* name) {
[email protected]2be6abf32012-06-26 00:28:334615 if (!StringIsValidForGLES(name)) {
[email protected]ab09b612013-03-11 22:11:514616 LOCAL_SET_GL_ERROR(
4617 GL_INVALID_VALUE,
4618 "glBindUniformLocationCHROMIUM", "Invalid character");
[email protected]2be6abf32012-06-26 00:28:334619 return;
4620 }
4621 if (ProgramManager::IsInvalidPrefix(name, strlen(name))) {
[email protected]ab09b612013-03-11 22:11:514622 LOCAL_SET_GL_ERROR(
4623 GL_INVALID_OPERATION,
4624 "glBindUniformLocationCHROMIUM", "reserved prefix");
[email protected]2be6abf32012-06-26 00:28:334625 return;
4626 }
4627 if (location < 0 || static_cast<uint32>(location) >=
4628 (group_->max_fragment_uniform_vectors() +
4629 group_->max_vertex_uniform_vectors()) * 4) {
[email protected]ab09b612013-03-11 22:11:514630 LOCAL_SET_GL_ERROR(
4631 GL_INVALID_VALUE,
4632 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334633 return;
4634 }
[email protected]df37b9932013-03-08 05:21:424635 Program* program = GetProgramInfoNotShader(
4636 program_id, "glBindUniformLocationCHROMIUM");
4637 if (!program) {
[email protected]2be6abf32012-06-26 00:28:334638 return;
4639 }
[email protected]df37b9932013-03-08 05:21:424640 if (!program->SetUniformLocationBinding(name, location)) {
[email protected]ab09b612013-03-11 22:11:514641 LOCAL_SET_GL_ERROR(
4642 GL_INVALID_VALUE,
4643 "glBindUniformLocationCHROMIUM", "location out of range");
[email protected]2be6abf32012-06-26 00:28:334644 }
4645}
4646
4647error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354648 uint32 immediate_data_size, const cmds::BindUniformLocationCHROMIUM& c) {
[email protected]2be6abf32012-06-26 00:28:334649 GLuint program = static_cast<GLuint>(c.program);
4650 GLint location = static_cast<GLint>(c.location);
4651 uint32 name_size = c.data_size;
4652 const char* name = GetSharedMemoryAs<const char*>(
4653 c.name_shm_id, c.name_shm_offset, name_size);
4654 if (name == NULL) {
4655 return error::kOutOfBounds;
4656 }
4657 String name_str(name, name_size);
4658 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4659 return error::kNoError;
4660}
4661
[email protected]2be6abf32012-06-26 00:28:334662error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
4663 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:354664 const cmds::BindUniformLocationCHROMIUMBucket& c) {
[email protected]2be6abf32012-06-26 00:28:334665 GLuint program = static_cast<GLuint>(c.program);
4666 GLint location = static_cast<GLint>(c.location);
4667 Bucket* bucket = GetBucket(c.name_bucket_id);
4668 if (!bucket || bucket->size() == 0) {
4669 return error::kInvalidArguments;
4670 }
4671 std::string name_str;
4672 if (!bucket->GetAsString(&name_str)) {
4673 return error::kInvalidArguments;
4674 }
4675 DoBindUniformLocationCHROMIUM(program, location, name_str.c_str());
4676 return error::kNoError;
4677}
4678
[email protected]f7a64ee2010-02-01 22:24:144679error::Error GLES2DecoderImpl::HandleDeleteShader(
[email protected]ed9f9cd2013-02-27 21:12:354680 uint32 immediate_data_size, const cmds::DeleteShader& c) {
[email protected]ae51d192010-04-27 00:48:034681 GLuint client_id = c.shader;
4682 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424683 Shader* shader = GetShader(client_id);
4684 if (shader) {
4685 if (!shader->IsDeleted()) {
4686 glDeleteShader(shader->service_id());
4687 shader_manager()->MarkAsDeleted(shader);
[email protected]ca488e12010-12-13 20:06:144688 }
[email protected]ae51d192010-04-27 00:48:034689 } else {
[email protected]ab09b612013-03-11 22:11:514690 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glDeleteShader", "unknown shader");
[email protected]ae51d192010-04-27 00:48:034691 }
[email protected]96449d2c2009-11-25 00:01:324692 }
[email protected]f7a64ee2010-02-01 22:24:144693 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324694}
4695
[email protected]f7a64ee2010-02-01 22:24:144696error::Error GLES2DecoderImpl::HandleDeleteProgram(
[email protected]ed9f9cd2013-02-27 21:12:354697 uint32 immediate_data_size, const cmds::DeleteProgram& c) {
[email protected]ae51d192010-04-27 00:48:034698 GLuint client_id = c.program;
4699 if (client_id) {
[email protected]df37b9932013-03-08 05:21:424700 Program* program = GetProgram(client_id);
4701 if (program) {
4702 if (!program->IsDeleted()) {
4703 program_manager()->MarkAsDeleted(shader_manager(), program);
[email protected]ca488e12010-12-13 20:06:144704 }
[email protected]ae51d192010-04-27 00:48:034705 } else {
[email protected]ab09b612013-03-11 22:11:514706 LOCAL_SET_GL_ERROR(
4707 GL_INVALID_VALUE, "glDeleteProgram", "unknown program");
[email protected]ae51d192010-04-27 00:48:034708 }
[email protected]96449d2c2009-11-25 00:01:324709 }
[email protected]f7a64ee2010-02-01 22:24:144710 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:324711}
4712
[email protected]269200b12010-11-18 22:53:064713void GLES2DecoderImpl::DoDeleteSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104714 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574715 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104716 for (GLsizei ii = 0; ii < n; ++ii) {
4717 id_allocator->FreeID(ids[ii]);
4718 }
4719}
4720
[email protected]269200b12010-11-18 22:53:064721error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354722 uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104723 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4724 GLsizei n = static_cast<GLsizei>(c.n);
4725 uint32 data_size;
4726 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4727 return error::kOutOfBounds;
4728 }
4729 const GLuint* ids = GetSharedMemoryAs<const GLuint*>(
4730 c.ids_shm_id, c.ids_shm_offset, data_size);
4731 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514732 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "DeleteSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104733 return error::kNoError;
4734 }
4735 if (ids == NULL) {
4736 return error::kOutOfBounds;
4737 }
[email protected]269200b12010-11-18 22:53:064738 DoDeleteSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104739 return error::kNoError;
4740}
4741
[email protected]269200b12010-11-18 22:53:064742void GLES2DecoderImpl::DoGenSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104743 GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574744 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104745 if (id_offset == 0) {
4746 for (GLsizei ii = 0; ii < n; ++ii) {
4747 ids[ii] = id_allocator->AllocateID();
4748 }
4749 } else {
4750 for (GLsizei ii = 0; ii < n; ++ii) {
4751 ids[ii] = id_allocator->AllocateIDAtOrAbove(id_offset);
4752 id_offset = ids[ii] + 1;
4753 }
4754 }
4755}
4756
[email protected]269200b12010-11-18 22:53:064757error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354758 uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104759 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4760 GLuint id_offset = static_cast<GLuint>(c.id_offset);
4761 GLsizei n = static_cast<GLsizei>(c.n);
4762 uint32 data_size;
4763 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4764 return error::kOutOfBounds;
4765 }
4766 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4767 c.ids_shm_id, c.ids_shm_offset, data_size);
4768 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514769 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "GenSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104770 return error::kNoError;
4771 }
4772 if (ids == NULL) {
4773 return error::kOutOfBounds;
4774 }
[email protected]269200b12010-11-18 22:53:064775 DoGenSharedIdsCHROMIUM(namespace_id, id_offset, n, ids);
[email protected]066849e32010-05-03 19:14:104776 return error::kNoError;
4777}
4778
[email protected]269200b12010-11-18 22:53:064779void GLES2DecoderImpl::DoRegisterSharedIdsCHROMIUM(
[email protected]066849e32010-05-03 19:14:104780 GLuint namespace_id, GLsizei n, const GLuint* ids) {
[email protected]3b1ecc262011-08-03 22:49:574781 IdAllocatorInterface* id_allocator = group_->GetIdAllocator(namespace_id);
[email protected]066849e32010-05-03 19:14:104782 for (GLsizei ii = 0; ii < n; ++ii) {
4783 if (!id_allocator->MarkAsUsed(ids[ii])) {
4784 for (GLsizei jj = 0; jj < ii; ++jj) {
4785 id_allocator->FreeID(ids[jj]);
4786 }
[email protected]ab09b612013-03-11 22:11:514787 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:434788 GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM",
4789 "attempt to register id that already exists");
[email protected]066849e32010-05-03 19:14:104790 return;
4791 }
4792 }
4793}
4794
[email protected]269200b12010-11-18 22:53:064795error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:354796 uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) {
[email protected]066849e32010-05-03 19:14:104797 GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
4798 GLsizei n = static_cast<GLsizei>(c.n);
4799 uint32 data_size;
4800 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
4801 return error::kOutOfBounds;
4802 }
4803 GLuint* ids = GetSharedMemoryAs<GLuint*>(
4804 c.ids_shm_id, c.ids_shm_offset, data_size);
4805 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:514806 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "RegisterSharedIdsCHROMIUM", "n < 0");
[email protected]066849e32010-05-03 19:14:104807 return error::kNoError;
4808 }
4809 if (ids == NULL) {
4810 return error::kOutOfBounds;
4811 }
[email protected]269200b12010-11-18 22:53:064812 DoRegisterSharedIdsCHROMIUM(namespace_id, n, ids);
[email protected]066849e32010-05-03 19:14:104813 return error::kNoError;
4814}
4815
[email protected]a7266a92012-06-28 02:11:084816error::Error GLES2DecoderImpl::DoClear(GLbitfield mask) {
[email protected]09e17272012-11-30 10:30:444817 DCHECK(!ShouldDeferDraws());
[email protected]0d6bfdc2011-11-02 01:32:204818 if (CheckBoundFramebuffersValid("glClear")) {
[email protected]297ca1c2011-06-20 23:08:464819 ApplyDirtyState();
[email protected]3a03a8f2011-03-19 00:51:274820 glClear(mask);
4821 }
[email protected]a7266a92012-06-28 02:11:084822 return error::kNoError;
4823}
4824
[email protected]36cef8ce2010-03-16 07:34:454825void GLES2DecoderImpl::DoFramebufferRenderbuffer(
4826 GLenum target, GLenum attachment, GLenum renderbuffertarget,
[email protected]ae51d192010-04-27 00:48:034827 GLuint client_renderbuffer_id) {
[email protected]4d8f0dd2013-03-09 14:37:064828 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4829 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514830 LOCAL_SET_GL_ERROR(
4831 GL_INVALID_OPERATION,
4832 "glFramebufferRenderbuffer", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:454833 return;
4834 }
[email protected]ae51d192010-04-27 00:48:034835 GLuint service_id = 0;
[email protected]ee2a79c32013-03-10 03:50:274836 Renderbuffer* renderbuffer = NULL;
[email protected]ae51d192010-04-27 00:48:034837 if (client_renderbuffer_id) {
[email protected]ee2a79c32013-03-10 03:50:274838 renderbuffer = GetRenderbuffer(client_renderbuffer_id);
4839 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:514840 LOCAL_SET_GL_ERROR(
4841 GL_INVALID_OPERATION,
4842 "glFramebufferRenderbuffer", "unknown renderbuffer");
[email protected]ae51d192010-04-27 00:48:034843 return;
4844 }
[email protected]ee2a79c32013-03-10 03:50:274845 service_id = renderbuffer->service_id();
[email protected]ae51d192010-04-27 00:48:034846 }
[email protected]ab09b612013-03-11 22:11:514847 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glFramebufferRenderbuffer");
[email protected]ae51d192010-04-27 00:48:034848 glFramebufferRenderbufferEXT(
4849 target, attachment, renderbuffertarget, service_id);
[email protected]ab09b612013-03-11 22:11:514850 GLenum error = LOCAL_PEEK_GL_ERROR("glFramebufferRenderbuffer");
[email protected]9edc6b22010-12-23 02:00:264851 if (error == GL_NO_ERROR) {
[email protected]ee2a79c32013-03-10 03:50:274852 framebuffer->AttachRenderbuffer(attachment, renderbuffer);
[email protected]3a2e7c7b2010-08-06 01:12:284853 }
[email protected]9d3b2e12013-10-02 01:04:344854 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:444855 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:464856 }
[email protected]81fc9d02013-03-14 23:53:324857 OnFboChanged();
[email protected]3a2e7c7b2010-08-06 01:12:284858}
4859
[email protected]3a2e7c7b2010-08-06 01:12:284860void GLES2DecoderImpl::DoDisable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464861 if (SetCapabilityState(cap, false)) {
4862 glDisable(cap);
4863 }
[email protected]3a2e7c7b2010-08-06 01:12:284864}
4865
4866void GLES2DecoderImpl::DoEnable(GLenum cap) {
[email protected]297ca1c2011-06-20 23:08:464867 if (SetCapabilityState(cap, true)) {
4868 glEnable(cap);
4869 }
[email protected]3a2e7c7b2010-08-06 01:12:284870}
4871
[email protected]88a61bf2012-10-27 13:00:424872void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) {
4873 state_.z_near = std::min(1.0f, std::max(0.0f, znear));
4874 state_.z_far = std::min(1.0f, std::max(0.0f, zfar));
4875 glDepthRange(znear, zfar);
[email protected]3a2e7c7b2010-08-06 01:12:284876}
4877
[email protected]b04e24c2013-01-08 18:35:254878void GLES2DecoderImpl::DoSampleCoverage(GLclampf value, GLboolean invert) {
[email protected]88a61bf2012-10-27 13:00:424879 state_.sample_coverage_value = std::min(1.0f, std::max(0.0f, value));
4880 state_.sample_coverage_invert = (invert != 0);
4881 glSampleCoverage(state_.sample_coverage_value, invert);
[email protected]3a2e7c7b2010-08-06 01:12:284882}
4883
[email protected]0d6bfdc2011-11-02 01:32:204884// Assumes framebuffer is complete.
4885void GLES2DecoderImpl::ClearUnclearedAttachments(
[email protected]4d8f0dd2013-03-09 14:37:064886 GLenum target, Framebuffer* framebuffer) {
[email protected]8e3e0662010-08-23 18:46:304887 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]0d6bfdc2011-11-02 01:32:204888 // bind this to the DRAW point, clear then bind back to READ
4889 // TODO(gman): I don't think there is any guarantee that an FBO that
4890 // is complete on the READ attachment will be complete as a DRAW
4891 // attachment.
4892 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
[email protected]4d8f0dd2013-03-09 14:37:064893 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer->service_id());
[email protected]8e3e0662010-08-23 18:46:304894 }
[email protected]3a2e7c7b2010-08-06 01:12:284895 GLbitfield clear_bits = 0;
[email protected]4d8f0dd2013-03-09 14:37:064896 if (framebuffer->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
[email protected]297ca1c2011-06-20 23:08:464897 glClearColor(
[email protected]0d6bfdc2011-11-02 01:32:204898 0.0f, 0.0f, 0.0f,
[email protected]297ca1c2011-06-20 23:08:464899 (GLES2Util::GetChannelsForFormat(
[email protected]4d8f0dd2013-03-09 14:37:064900 framebuffer->GetColorAttachmentFormat()) & 0x0008) != 0 ? 0.0f :
4901 1.0f);
[email protected]3a2e7c7b2010-08-06 01:12:284902 glColorMask(true, true, true, true);
4903 clear_bits |= GL_COLOR_BUFFER_BIT;
4904 }
4905
[email protected]4d8f0dd2013-03-09 14:37:064906 if (framebuffer->HasUnclearedAttachment(GL_STENCIL_ATTACHMENT) ||
4907 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284908 glClearStencil(0);
4909 glStencilMask(-1);
4910 clear_bits |= GL_STENCIL_BUFFER_BIT;
4911 }
4912
[email protected]4d8f0dd2013-03-09 14:37:064913 if (framebuffer->HasUnclearedAttachment(GL_DEPTH_ATTACHMENT) ||
4914 framebuffer->HasUnclearedAttachment(GL_DEPTH_STENCIL_ATTACHMENT)) {
[email protected]3a2e7c7b2010-08-06 01:12:284915 glClearDepth(1.0f);
4916 glDepthMask(true);
4917 clear_bits |= GL_DEPTH_BUFFER_BIT;
4918 }
4919
4920 glDisable(GL_SCISSOR_TEST);
4921 glClear(clear_bits);
4922
[email protected]968351b2011-12-20 08:26:514923 framebuffer_manager()->MarkAttachmentsAsCleared(
[email protected]4d8f0dd2013-03-09 14:37:064924 framebuffer, renderbuffer_manager(), texture_manager());
[email protected]3a2e7c7b2010-08-06 01:12:284925
[email protected]c007aa02010-09-02 22:22:404926 RestoreClearState();
4927
4928 if (target == GL_READ_FRAMEBUFFER_EXT) {
[email protected]4d8f0dd2013-03-09 14:37:064929 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer->service_id());
4930 Framebuffer* draw_framebuffer =
[email protected]87d1a3fe2011-12-01 04:25:484931 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
[email protected]4d8f0dd2013-03-09 14:37:064932 GLuint service_id = draw_framebuffer ? draw_framebuffer->service_id() :
4933 GetBackbufferServiceId();
[email protected]87d1a3fe2011-12-01 04:25:484934 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, service_id);
[email protected]c007aa02010-09-02 22:22:404935 }
4936}
4937
4938void GLES2DecoderImpl::RestoreClearState() {
[email protected]c986af502013-08-14 01:04:444939 framebuffer_state_.clear_state_dirty = true;
[email protected]e259eb412012-10-13 05:47:244940 glClearColor(
4941 state_.color_clear_red, state_.color_clear_green, state_.color_clear_blue,
4942 state_.color_clear_alpha);
4943 glClearStencil(state_.stencil_clear);
4944 glClearDepth(state_.depth_clear);
[email protected]f731b9462012-10-30 00:35:224945 if (state_.enable_flags.scissor_test) {
[email protected]3a2e7c7b2010-08-06 01:12:284946 glEnable(GL_SCISSOR_TEST);
4947 }
[email protected]36cef8ce2010-03-16 07:34:454948}
4949
4950GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
[email protected]ed9f9cd2013-02-27 21:12:354951 Framebuffer* framebuffer =
[email protected]8e3e0662010-08-23 18:46:304952 GetFramebufferInfoForTarget(target);
[email protected]0d6bfdc2011-11-02 01:32:204953 if (!framebuffer) {
[email protected]36cef8ce2010-03-16 07:34:454954 return GL_FRAMEBUFFER_COMPLETE;
4955 }
[email protected]0d6bfdc2011-11-02 01:32:204956 GLenum completeness = framebuffer->IsPossiblyComplete();
4957 if (completeness != GL_FRAMEBUFFER_COMPLETE) {
4958 return completeness;
4959 }
[email protected]73276522012-11-09 05:50:204960 return framebuffer->GetStatus(texture_manager(), target);
[email protected]36cef8ce2010-03-16 07:34:454961}
4962
4963void GLES2DecoderImpl::DoFramebufferTexture2D(
[email protected]ae51d192010-04-27 00:48:034964 GLenum target, GLenum attachment, GLenum textarget,
4965 GLuint client_texture_id, GLint level) {
[email protected]7d3c36e2013-07-12 14:13:164966 DoFramebufferTexture2DCommon(
4967 "glFramebufferTexture2D", target, attachment,
4968 textarget, client_texture_id, level, 0);
4969}
4970
4971void GLES2DecoderImpl::DoFramebufferTexture2DMultisample(
4972 GLenum target, GLenum attachment, GLenum textarget,
4973 GLuint client_texture_id, GLint level, GLsizei samples) {
4974 if (!features().multisampled_render_to_texture) {
4975 LOCAL_SET_GL_ERROR(
4976 GL_INVALID_OPERATION,
4977 "glFramebufferTexture2DMultisample", "function not available");
4978 return;
4979 }
4980 DoFramebufferTexture2DCommon(
4981 "glFramebufferTexture2DMultisample", target, attachment,
4982 textarget, client_texture_id, level, samples);
4983}
4984
4985void GLES2DecoderImpl::DoFramebufferTexture2DCommon(
4986 const char* name, GLenum target, GLenum attachment, GLenum textarget,
4987 GLuint client_texture_id, GLint level, GLsizei samples) {
4988 if (samples > renderbuffer_manager()->max_samples()) {
4989 LOCAL_SET_GL_ERROR(
4990 GL_INVALID_VALUE,
4991 "glFramebufferTexture2DMultisample", "samples too large");
4992 return;
4993 }
[email protected]4d8f0dd2013-03-09 14:37:064994 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
4995 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:514996 LOCAL_SET_GL_ERROR(
4997 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:164998 name, "no framebuffer bound.");
[email protected]36cef8ce2010-03-16 07:34:454999 return;
5000 }
[email protected]ae51d192010-04-27 00:48:035001 GLuint service_id = 0;
[email protected]370eaf12013-05-18 09:19:495002 TextureRef* texture_ref = NULL;
[email protected]ae51d192010-04-27 00:48:035003 if (client_texture_id) {
[email protected]370eaf12013-05-18 09:19:495004 texture_ref = GetTexture(client_texture_id);
5005 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:515006 LOCAL_SET_GL_ERROR(
5007 GL_INVALID_OPERATION,
[email protected]7d3c36e2013-07-12 14:13:165008 name, "unknown texture_ref");
[email protected]ae51d192010-04-27 00:48:035009 return;
5010 }
[email protected]370eaf12013-05-18 09:19:495011 service_id = texture_ref->service_id();
[email protected]ae51d192010-04-27 00:48:035012 }
[email protected]0d6bfdc2011-11-02 01:32:205013
[email protected]80eb6b52012-01-19 00:14:415014 if (!texture_manager()->ValidForTarget(textarget, level, 0, 0, 1)) {
[email protected]ab09b612013-03-11 22:11:515015 LOCAL_SET_GL_ERROR(
5016 GL_INVALID_VALUE,
[email protected]7d3c36e2013-07-12 14:13:165017 name, "level out of range");
[email protected]0d6bfdc2011-11-02 01:32:205018 return;
5019 }
5020
[email protected]91c94eb2013-10-22 10:32:545021 if (texture_ref)
5022 DoWillUseTexImageIfNeeded(texture_ref->texture(), textarget);
5023
[email protected]7d3c36e2013-07-12 14:13:165024 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(name);
5025 if (0 == samples) {
5026 glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
5027 } else {
5028 if (features().use_img_for_multisampled_render_to_texture) {
5029 glFramebufferTexture2DMultisampleIMG(target, attachment, textarget,
5030 service_id, level, samples);
5031 } else {
5032 glFramebufferTexture2DMultisampleEXT(target, attachment, textarget,
5033 service_id, level, samples);
5034 }
5035 }
5036 GLenum error = LOCAL_PEEK_GL_ERROR(name);
[email protected]9edc6b22010-12-23 02:00:265037 if (error == GL_NO_ERROR) {
[email protected]7d3c36e2013-07-12 14:13:165038 framebuffer->AttachTexture(attachment, texture_ref, textarget, level,
5039 samples);
[email protected]3a2e7c7b2010-08-06 01:12:285040 }
[email protected]9d3b2e12013-10-02 01:04:345041 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) {
[email protected]c986af502013-08-14 01:04:445042 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:465043 }
[email protected]91c94eb2013-10-22 10:32:545044
5045 if (texture_ref)
5046 DoDidUseTexImageIfNeeded(texture_ref->texture(), textarget);
5047
[email protected]81fc9d02013-03-14 23:53:325048 OnFboChanged();
[email protected]36cef8ce2010-03-16 07:34:455049}
5050
5051void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
5052 GLenum target, GLenum attachment, GLenum pname, GLint* params) {
[email protected]4d8f0dd2013-03-09 14:37:065053 Framebuffer* framebuffer = GetFramebufferInfoForTarget(target);
5054 if (!framebuffer) {
[email protected]ab09b612013-03-11 22:11:515055 LOCAL_SET_GL_ERROR(
5056 GL_INVALID_OPERATION,
5057 "glFramebufferAttachmentParameteriv", "no framebuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455058 return;
5059 }
[email protected]74c1ec42010-08-12 01:55:575060 if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) {
[email protected]62e65f02013-05-29 22:28:105061 const Framebuffer::Attachment* attachment_object =
5062 framebuffer->GetAttachment(attachment);
5063 *params = attachment_object ? attachment_object->object_name() : 0;
5064 } else {
[email protected]7d3c36e2013-07-12 14:13:165065 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT &&
5066 features().use_img_for_multisampled_render_to_texture) {
5067 pname = GL_TEXTURE_SAMPLES_IMG;
5068 }
[email protected]62e65f02013-05-29 22:28:105069 glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
[email protected]74c1ec42010-08-12 01:55:575070 }
[email protected]36cef8ce2010-03-16 07:34:455071}
5072
5073void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
5074 GLenum target, GLenum pname, GLint* params) {
[email protected]ed9f9cd2013-02-27 21:12:355075 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205076 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5077 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515078 LOCAL_SET_GL_ERROR(
5079 GL_INVALID_OPERATION,
5080 "glGetRenderbufferParameteriv", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455081 return;
5082 }
[email protected]3a03a8f2011-03-19 00:51:275083 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:435084 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5085 *params = renderbuffer->internal_format();
5086 break;
5087 case GL_RENDERBUFFER_WIDTH:
5088 *params = renderbuffer->width();
5089 break;
5090 case GL_RENDERBUFFER_HEIGHT:
5091 *params = renderbuffer->height();
5092 break;
[email protected]7d3c36e2013-07-12 14:13:165093 case GL_RENDERBUFFER_SAMPLES_EXT:
5094 if (features().use_img_for_multisampled_render_to_texture) {
5095 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_IMG,
5096 params);
5097 } else {
5098 glGetRenderbufferParameterivEXT(target, GL_RENDERBUFFER_SAMPLES_EXT,
5099 params);
5100 }
[email protected]ad84a3a2012-06-08 21:42:435101 default:
5102 glGetRenderbufferParameterivEXT(target, pname, params);
5103 break;
[email protected]b71f52c2010-06-18 22:20:205104 }
[email protected]36cef8ce2010-03-16 07:34:455105}
5106
[email protected]49cabed2013-11-13 18:15:185107void GLES2DecoderImpl::DoBlitFramebufferCHROMIUM(
[email protected]8e3e0662010-08-23 18:46:305108 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
5109 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5110 GLbitfield mask, GLenum filter) {
[email protected]09e17272012-11-30 10:30:445111 DCHECK(!ShouldDeferReads() && !ShouldDeferDraws());
[email protected]62e155e2012-10-23 22:43:155112 if (!features().chromium_framebuffer_multisample) {
[email protected]ab09b612013-03-11 22:11:515113 LOCAL_SET_GL_ERROR(
5114 GL_INVALID_OPERATION,
[email protected]49cabed2013-11-13 18:15:185115 "glBlitFramebufferCHROMIUM", "function not available");
[email protected]680aa412013-10-31 18:08:015116 return;
[email protected]8e3e0662010-08-23 18:46:305117 }
[email protected]0c16343f2013-03-08 20:40:165118
[email protected]49cabed2013-11-13 18:15:185119 if (!CheckBoundFramebuffersValid("glBlitFramebufferCHROMIUM")) {
[email protected]0c16343f2013-03-08 20:40:165120 return;
5121 }
5122
[email protected]d058bca2012-11-26 10:27:265123 glDisable(GL_SCISSOR_TEST);
[email protected]f42f05b2013-11-15 21:46:185124 BlitFramebufferHelper(
5125 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5126 EnableDisable(GL_SCISSOR_TEST, state_.enable_flags.scissor_test);
5127}
5128
5129void GLES2DecoderImpl::RenderbufferStorageMultisampleHelper(
5130 const FeatureInfo* feature_info,
5131 GLenum target,
5132 GLsizei samples,
5133 GLenum internal_format,
5134 GLsizei width,
5135 GLsizei height) {
5136 // TODO(sievers): This could be resolved at the GL binding level, but the
5137 // binding process is currently a bit too 'brute force'.
5138 if (feature_info->feature_flags().is_angle) {
5139 glRenderbufferStorageMultisampleANGLE(
5140 target, samples, internal_format, width, height);
5141 } else if (feature_info->feature_flags().use_core_framebuffer_multisample) {
5142 glRenderbufferStorageMultisample(
5143 target, samples, internal_format, width, height);
5144 } else {
5145 glRenderbufferStorageMultisampleEXT(
5146 target, samples, internal_format, width, height);
5147 }
5148}
5149
5150void GLES2DecoderImpl::BlitFramebufferHelper(GLint srcX0,
5151 GLint srcY0,
5152 GLint srcX1,
5153 GLint srcY1,
5154 GLint dstX0,
5155 GLint dstY0,
5156 GLint dstX1,
5157 GLint dstY1,
5158 GLbitfield mask,
5159 GLenum filter) {
5160 // TODO(sievers): This could be resolved at the GL binding level, but the
5161 // binding process is currently a bit too 'brute force'.
5162 if (feature_info_->feature_flags().is_angle) {
[email protected]5094b0f2010-11-09 19:45:245163 glBlitFramebufferANGLE(
5164 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]f42f05b2013-11-15 21:46:185165 } else if (feature_info_->feature_flags().use_core_framebuffer_multisample) {
5166 glBlitFramebuffer(
5167 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
[email protected]5094b0f2010-11-09 19:45:245168 } else {
5169 glBlitFramebufferEXT(
5170 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5171 }
[email protected]8e3e0662010-08-23 18:46:305172}
5173
[email protected]49cabed2013-11-13 18:15:185174bool GLES2DecoderImpl::ValidateRenderbufferStorageMultisample(
5175 GLsizei samples,
5176 GLenum internalformat,
5177 GLsizei width,
5178 GLsizei height) {
[email protected]84afefa2011-10-19 21:45:535179 if (samples > renderbuffer_manager()->max_samples()) {
[email protected]ab09b612013-03-11 22:11:515180 LOCAL_SET_GL_ERROR(
5181 GL_INVALID_VALUE,
5182 "glRenderbufferStorageMultisample", "samples too large");
[email protected]49cabed2013-11-13 18:15:185183 return false;
[email protected]84afefa2011-10-19 21:45:535184 }
5185
5186 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5187 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515188 LOCAL_SET_GL_ERROR(
5189 GL_INVALID_VALUE,
5190 "glRenderbufferStorageMultisample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185191 return false;
[email protected]84afefa2011-10-19 21:45:535192 }
5193
[email protected]7989c9e2013-01-23 06:39:265194 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235195 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5196 width, height, samples, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515197 LOCAL_SET_GL_ERROR(
5198 GL_OUT_OF_MEMORY,
5199 "glRenderbufferStorageMultsample", "dimensions too large");
[email protected]49cabed2013-11-13 18:15:185200 return false;
[email protected]8e3e0662010-08-23 18:46:305201 }
5202
[email protected]7989c9e2013-01-23 06:39:265203 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515204 LOCAL_SET_GL_ERROR(
5205 GL_OUT_OF_MEMORY,
5206 "glRenderbufferStorageMultsample", "out of memory");
[email protected]49cabed2013-11-13 18:15:185207 return false;
5208 }
5209
5210 return true;
5211}
5212
5213void GLES2DecoderImpl::DoRenderbufferStorageMultisampleCHROMIUM(
5214 GLenum target, GLsizei samples, GLenum internalformat,
5215 GLsizei width, GLsizei height) {
5216 if (!features().chromium_framebuffer_multisample) {
5217 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5218 "glRenderbufferStorageMultisampleCHROMIUM",
5219 "function not available");
5220 return;
5221 }
5222
5223 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5224 if (!renderbuffer) {
5225 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5226 "glRenderbufferStorageMultisampleCHROMIUM",
5227 "no renderbuffer bound");
5228 return;
5229 }
5230
5231 if (!ValidateRenderbufferStorageMultisample(
5232 samples, internalformat, width, height)) {
[email protected]7989c9e2013-01-23 06:39:265233 return;
5234 }
5235
[email protected]8e102e102013-09-20 22:50:235236 GLenum impl_format =
5237 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5238 internalformat);
[email protected]49cabed2013-11-13 18:15:185239 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(
5240 "glRenderbufferStorageMultisampleCHROMIUM");
[email protected]f42f05b2013-11-15 21:46:185241 RenderbufferStorageMultisampleHelper(
5242 feature_info_, target, samples, impl_format, width, height);
[email protected]49cabed2013-11-13 18:15:185243 GLenum error =
5244 LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleCHROMIUM");
[email protected]9edc6b22010-12-23 02:00:265245 if (error == GL_NO_ERROR) {
[email protected]4a4c18b2013-09-13 22:50:105246
5247 if (workarounds().validate_multisample_buffer_allocation) {
5248 if (!VerifyMultisampleRenderbufferIntegrity(
5249 renderbuffer->service_id(), impl_format)) {
5250 LOCAL_SET_GL_ERROR(
5251 GL_OUT_OF_MEMORY,
[email protected]49cabed2013-11-13 18:15:185252 "glRenderbufferStorageMultisampleCHROMIUM", "out of memory");
[email protected]4a4c18b2013-09-13 22:50:105253 return;
5254 }
5255 }
5256
[email protected]968351b2011-12-20 08:26:515257 // TODO(gman): If renderbuffers tracked which framebuffers they were
5258 // attached to we could just mark those framebuffers as not complete.
5259 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205260 renderbuffer_manager()->SetInfo(
5261 renderbuffer, samples, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265262 }
[email protected]8e3e0662010-08-23 18:46:305263}
5264
[email protected]49cabed2013-11-13 18:15:185265// This is the handler for multisampled_render_to_texture extensions.
5266void GLES2DecoderImpl::DoRenderbufferStorageMultisampleEXT(
5267 GLenum target, GLsizei samples, GLenum internalformat,
5268 GLsizei width, GLsizei height) {
5269 if (!features().multisampled_render_to_texture) {
5270 LOCAL_SET_GL_ERROR(
5271 GL_INVALID_OPERATION,
5272 "glRenderbufferStorageMultisampleEXT", "function not available");
5273 return;
5274 }
5275
5276 Renderbuffer* renderbuffer = GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5277 if (!renderbuffer) {
5278 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
5279 "glRenderbufferStorageMultisampleEXT",
5280 "no renderbuffer bound");
5281 return;
5282 }
5283
5284 if (!ValidateRenderbufferStorageMultisample(
5285 samples, internalformat, width, height)) {
5286 return;
5287 }
5288
5289 GLenum impl_format =
5290 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5291 internalformat);
5292 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorageMultisampleEXT");
5293 if (features().use_img_for_multisampled_render_to_texture) {
5294 glRenderbufferStorageMultisampleIMG(
5295 target, samples, impl_format, width, height);
5296 } else {
5297 glRenderbufferStorageMultisampleEXT(
5298 target, samples, impl_format, width, height);
5299 }
5300 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorageMultisampleEXT");
5301 if (error == GL_NO_ERROR) {
5302 // TODO(gman): If renderbuffers tracked which framebuffers they were
5303 // attached to we could just mark those framebuffers as not complete.
5304 framebuffer_manager()->IncFramebufferStateChangeCount();
5305 renderbuffer_manager()->SetInfo(
5306 renderbuffer, samples, internalformat, width, height);
5307 }
5308}
5309
[email protected]4a4c18b2013-09-13 22:50:105310// This function validates the allocation of a multisampled renderbuffer
5311// by clearing it to a key color, blitting the contents to a texture, and
5312// reading back the color to ensure it matches the key.
5313bool GLES2DecoderImpl::VerifyMultisampleRenderbufferIntegrity(
5314 GLuint renderbuffer, GLenum format) {
5315
5316 // Only validate color buffers.
5317 // These formats have been selected because they are very common or are known
5318 // to be used by the WebGL backbuffer. If problems are observed with other
5319 // color formats they can be added here.
5320 switch(format) {
5321 case GL_RGB:
5322 case GL_RGB8:
5323 case GL_RGBA:
5324 case GL_RGBA8:
5325 break;
5326 default:
5327 return true;
5328 }
5329
5330 GLint draw_framebuffer, read_framebuffer;
5331
5332 // Cache framebuffer and texture bindings.
5333 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_framebuffer);
5334 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_framebuffer);
5335
5336 if (!validation_texture_) {
5337 GLint bound_texture;
5338 glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound_texture);
5339
5340 // Create additional resources needed for the verification.
5341 glGenTextures(1, &validation_texture_);
5342 glGenFramebuffersEXT(1, &validation_fbo_multisample_);
5343 glGenFramebuffersEXT(1, &validation_fbo_);
5344
5345 // Texture only needs to be 1x1.
5346 glBindTexture(GL_TEXTURE_2D, validation_texture_);
5347 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB,
5348 GL_UNSIGNED_BYTE, NULL);
5349
5350 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5351 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5352 GL_TEXTURE_2D, validation_texture_, 0);
5353
5354 glBindTexture(GL_TEXTURE_2D, bound_texture);
5355 }
5356
5357 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5358 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5359 GL_RENDERBUFFER, renderbuffer);
5360
5361 // Cache current state and reset it to the values we require.
5362 GLboolean scissor_enabled = false;
5363 glGetBooleanv(GL_SCISSOR_TEST, &scissor_enabled);
5364 if (scissor_enabled)
5365 glDisable(GL_SCISSOR_TEST);
5366
5367 GLboolean color_mask[4] = {true, true, true, true};
5368 glGetBooleanv(GL_COLOR_WRITEMASK, color_mask);
5369 glColorMask(true, true, true, true);
5370
5371 GLfloat clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
5372 glGetFloatv(GL_COLOR_CLEAR_VALUE, clear_color);
5373 glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
5374
5375 // Clear the buffer to the desired key color.
5376 glClear(GL_COLOR_BUFFER_BIT);
5377
5378 // Blit from the multisample buffer to a standard texture.
5379 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, validation_fbo_multisample_);
5380 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, validation_fbo_);
5381
[email protected]f42f05b2013-11-15 21:46:185382 BlitFramebufferHelper(
5383 0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
[email protected]4a4c18b2013-09-13 22:50:105384
5385 // Read a pixel from the buffer.
5386 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_);
5387
5388 unsigned char pixel[3] = {0, 0, 0};
5389 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &pixel);
5390
5391 // Detach the renderbuffer.
5392 glBindFramebufferEXT(GL_FRAMEBUFFER, validation_fbo_multisample_);
5393 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
5394 GL_RENDERBUFFER, 0);
5395
5396 // Restore cached state.
5397 if (scissor_enabled)
5398 glEnable(GL_SCISSOR_TEST);
5399
5400 glColorMask(color_mask[0], color_mask[1], color_mask[2], color_mask[3]);
5401 glClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]);
5402 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, draw_framebuffer);
5403 glBindFramebufferEXT(GL_READ_FRAMEBUFFER, read_framebuffer);
5404
5405 // Return true if the pixel matched the desired key color.
5406 return (pixel[0] == 0xFF &&
5407 pixel[1] == 0x00 &&
5408 pixel[2] == 0xFF);
5409}
5410
[email protected]36cef8ce2010-03-16 07:34:455411void GLES2DecoderImpl::DoRenderbufferStorage(
5412 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
[email protected]ed9f9cd2013-02-27 21:12:355413 Renderbuffer* renderbuffer =
[email protected]0d6bfdc2011-11-02 01:32:205414 GetRenderbufferInfoForTarget(GL_RENDERBUFFER);
5415 if (!renderbuffer) {
[email protected]ab09b612013-03-11 22:11:515416 LOCAL_SET_GL_ERROR(
5417 GL_INVALID_OPERATION,
5418 "glRenderbufferStorage", "no renderbuffer bound");
[email protected]36cef8ce2010-03-16 07:34:455419 return;
5420 }
[email protected]876f6fee2010-08-02 23:10:325421
[email protected]84afefa2011-10-19 21:45:535422 if (width > renderbuffer_manager()->max_renderbuffer_size() ||
5423 height > renderbuffer_manager()->max_renderbuffer_size()) {
[email protected]ab09b612013-03-11 22:11:515424 LOCAL_SET_GL_ERROR(
5425 GL_INVALID_VALUE, "glRenderbufferStorage", "dimensions too large");
[email protected]84afefa2011-10-19 21:45:535426 return;
5427 }
5428
[email protected]7989c9e2013-01-23 06:39:265429 uint32 estimated_size = 0;
[email protected]8e102e102013-09-20 22:50:235430 if (!renderbuffer_manager()->ComputeEstimatedRenderbufferSize(
5431 width, height, 1, internalformat, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515432 LOCAL_SET_GL_ERROR(
5433 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:265434 return;
5435 }
5436
5437 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:515438 LOCAL_SET_GL_ERROR(
5439 GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory");
[email protected]7989c9e2013-01-23 06:39:265440 return;
[email protected]b71f52c2010-06-18 22:20:205441 }
[email protected]876f6fee2010-08-02 23:10:325442
[email protected]ab09b612013-03-11 22:11:515443 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glRenderbufferStorage");
[email protected]7989c9e2013-01-23 06:39:265444 glRenderbufferStorageEXT(
[email protected]8e102e102013-09-20 22:50:235445 target,
5446 renderbuffer_manager()->InternalRenderbufferFormatToImplFormat(
5447 internalformat),
5448 width,
5449 height);
[email protected]ab09b612013-03-11 22:11:515450 GLenum error = LOCAL_PEEK_GL_ERROR("glRenderbufferStorage");
[email protected]9edc6b22010-12-23 02:00:265451 if (error == GL_NO_ERROR) {
[email protected]968351b2011-12-20 08:26:515452 // TODO(gman): If tetxures tracked which framebuffers they were attached to
5453 // we could just mark those framebuffers as not complete.
5454 framebuffer_manager()->IncFramebufferStateChangeCount();
[email protected]0d6bfdc2011-11-02 01:32:205455 renderbuffer_manager()->SetInfo(
[email protected]7989c9e2013-01-23 06:39:265456 renderbuffer, 1, internalformat, width, height);
[email protected]9edc6b22010-12-23 02:00:265457 }
[email protected]36cef8ce2010-03-16 07:34:455458}
5459
[email protected]df37b9932013-03-08 05:21:425460void GLES2DecoderImpl::DoLinkProgram(GLuint program_id) {
[email protected]43ed3a72012-05-30 22:55:385461 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoLinkProgram");
[email protected]df37b9932013-03-08 05:21:425462 Program* program = GetProgramInfoNotShader(
5463 program_id, "glLinkProgram");
5464 if (!program) {
[email protected]a93bb842010-02-16 23:03:475465 return;
5466 }
[email protected]05afda12011-01-20 00:17:345467
[email protected]df37b9932013-03-08 05:21:425468 LogClientServiceForInfo(program, program_id, "glLinkProgram");
[email protected]65dfc602012-07-23 20:39:395469 ShaderTranslator* vertex_translator = NULL;
5470 ShaderTranslator* fragment_translator = NULL;
5471 if (use_shader_translator_) {
[email protected]7cd76fd2013-06-02 21:11:115472 vertex_translator = vertex_translator_.get();
5473 fragment_translator = fragment_translator_.get();
[email protected]65dfc602012-07-23 20:39:395474 }
[email protected]df37b9932013-03-08 05:21:425475 if (program->Link(shader_manager(),
[email protected]7cd76fd2013-06-02 21:11:115476 vertex_translator,
5477 fragment_translator,
5478 feature_info_.get(),
5479 shader_cache_callback_)) {
[email protected]df37b9932013-03-08 05:21:425480 if (program == state_.current_program.get()) {
[email protected]62e155e2012-10-23 22:43:155481 if (workarounds().use_current_program_after_successful_link) {
[email protected]df37b9932013-03-08 05:21:425482 glUseProgram(program->service_id());
[email protected]c2a3caf12012-10-23 19:32:005483 }
[email protected]df37b9932013-03-08 05:21:425484 program_manager()->ClearUniforms(program);
[email protected]2df73892012-04-28 01:09:545485 }
5486 }
[email protected]07f54fcc2009-12-22 02:46:305487};
5488
[email protected]3916c97e2010-02-25 03:20:505489void GLES2DecoderImpl::DoTexParameterf(
5490 GLenum target, GLenum pname, GLfloat param) {
[email protected]c986af502013-08-14 01:04:445491 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5492 &state_, target);
[email protected]02965c22013-03-09 02:40:075493 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515494 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterf", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245495 return;
[email protected]07f54fcc2009-12-22 02:46:305496 }
[email protected]cbb22e42011-05-12 23:36:245497
[email protected]02965c22013-03-09 02:40:075498 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505499 "glTexParameterf", GetErrorState(), texture, pname,
5500 static_cast<GLint>(param));
[email protected]07f54fcc2009-12-22 02:46:305501}
5502
[email protected]3916c97e2010-02-25 03:20:505503void GLES2DecoderImpl::DoTexParameteri(
5504 GLenum target, GLenum pname, GLint param) {
[email protected]c986af502013-08-14 01:04:445505 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5506 &state_, target);
[email protected]02965c22013-03-09 02:40:075507 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515508 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameteri", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245509 return;
[email protected]3916c97e2010-02-25 03:20:505510 }
[email protected]cbb22e42011-05-12 23:36:245511
[email protected]02965c22013-03-09 02:40:075512 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505513 "glTexParameteri", GetErrorState(), texture, pname, param);
[email protected]3916c97e2010-02-25 03:20:505514}
5515
5516void GLES2DecoderImpl::DoTexParameterfv(
5517 GLenum target, GLenum pname, const GLfloat* params) {
[email protected]c986af502013-08-14 01:04:445518 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5519 &state_, target);
[email protected]02965c22013-03-09 02:40:075520 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515521 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glTexParameterfv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245522 return;
[email protected]3916c97e2010-02-25 03:20:505523 }
[email protected]cbb22e42011-05-12 23:36:245524
[email protected]02965c22013-03-09 02:40:075525 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505526 "glTexParameterfv", GetErrorState(), texture, pname,
5527 static_cast<GLint>(params[0]));
[email protected]3916c97e2010-02-25 03:20:505528}
5529
5530void GLES2DecoderImpl::DoTexParameteriv(
5531 GLenum target, GLenum pname, const GLint* params) {
[email protected]c986af502013-08-14 01:04:445532 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
5533 &state_, target);
[email protected]02965c22013-03-09 02:40:075534 if (!texture) {
[email protected]ab09b612013-03-11 22:11:515535 LOCAL_SET_GL_ERROR(
5536 GL_INVALID_VALUE, "glTexParameteriv", "unknown texture");
[email protected]cbb22e42011-05-12 23:36:245537 return;
[email protected]3916c97e2010-02-25 03:20:505538 }
[email protected]cbb22e42011-05-12 23:36:245539
[email protected]02965c22013-03-09 02:40:075540 texture_manager()->SetParameter(
[email protected]d3eba342013-04-18 21:11:505541 "glTexParameteriv", GetErrorState(), texture, pname, *params);
[email protected]3916c97e2010-02-25 03:20:505542}
5543
[email protected]939e7362010-05-13 20:49:105544bool GLES2DecoderImpl::CheckCurrentProgram(const char* function_name) {
[email protected]7cd76fd2013-06-02 21:11:115545 if (!state_.current_program.get()) {
[email protected]ad84a3a2012-06-08 21:42:435546 // The program does not exist.
[email protected]ab09b612013-03-11 22:11:515547 LOCAL_SET_GL_ERROR(
5548 GL_INVALID_OPERATION, function_name, "no program in use");
[email protected]ad84a3a2012-06-08 21:42:435549 return false;
[email protected]939e7362010-05-13 20:49:105550 }
[email protected]e259eb412012-10-13 05:47:245551 if (!state_.current_program->InUse()) {
[email protected]ab09b612013-03-11 22:11:515552 LOCAL_SET_GL_ERROR(
5553 GL_INVALID_OPERATION, function_name, "program not linked");
[email protected]939e7362010-05-13 20:49:105554 return false;
5555 }
5556 return true;
5557}
5558
5559bool GLES2DecoderImpl::CheckCurrentProgramForUniform(
5560 GLint location, const char* function_name) {
5561 if (!CheckCurrentProgram(function_name)) {
5562 return false;
5563 }
5564 return location != -1;
5565}
5566
[email protected]476ccb72012-12-06 15:52:525567namespace {
5568
5569static const GLenum valid_int_vec1_types_list[] = {
5570 GL_INT,
5571 GL_BOOL,
5572 GL_SAMPLER_2D,
5573 GL_SAMPLER_2D_RECT_ARB,
5574 GL_SAMPLER_CUBE,
5575 GL_SAMPLER_EXTERNAL_OES,
5576};
5577
5578static const GLenum valid_int_vec2_types_list[] = {
5579 GL_INT_VEC2,
5580 GL_BOOL_VEC2,
5581};
5582
5583static const GLenum valid_int_vec3_types_list[] = {
5584 GL_INT_VEC3,
5585 GL_BOOL_VEC3,
5586};
5587
5588static const GLenum valid_int_vec4_types_list[] = {
5589 GL_INT_VEC4,
5590 GL_BOOL_VEC4,
5591};
5592
5593static const GLenum valid_float_vec1_types_list[] = {
5594 GL_FLOAT,
5595 GL_BOOL,
5596};
5597
5598static const GLenum valid_float_vec2_types_list[] = {
5599 GL_FLOAT_VEC2,
5600 GL_BOOL_VEC2,
5601};
5602
5603static const GLenum valid_float_vec3_types_list[] = {
5604 GL_FLOAT_VEC3,
5605 GL_BOOL_VEC3,
5606};
5607
5608static const GLenum valid_float_vec4_types_list[] = {
5609 GL_FLOAT_VEC4,
5610 GL_BOOL_VEC4,
5611};
5612
5613static const GLenum valid_float_mat2_types_list[] = {
5614 GL_FLOAT_MAT2,
5615};
5616
5617static const GLenum valid_float_mat3_types_list[] = {
5618 GL_FLOAT_MAT3,
5619};
5620
5621static const GLenum valid_float_mat4_types_list[] = {
5622 GL_FLOAT_MAT4,
5623};
5624
5625static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec1_base_info = {
5626 valid_int_vec1_types_list,
5627 arraysize(valid_int_vec1_types_list),
5628};
5629
5630static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec2_base_info = {
5631 valid_int_vec2_types_list,
5632 arraysize(valid_int_vec2_types_list),
5633};
5634
5635static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec3_base_info = {
5636 valid_int_vec3_types_list,
5637 arraysize(valid_int_vec3_types_list),
5638};
5639
5640static const GLES2DecoderImpl::BaseUniformInfo valid_int_vec4_base_info = {
5641 valid_int_vec4_types_list,
5642 arraysize(valid_int_vec4_types_list),
5643};
5644
5645static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec1_base_info = {
5646 valid_float_vec1_types_list,
5647 arraysize(valid_float_vec1_types_list),
5648};
5649
5650static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec2_base_info = {
5651 valid_float_vec2_types_list,
5652 arraysize(valid_float_vec2_types_list),
5653};
5654
5655static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec3_base_info = {
5656 valid_float_vec3_types_list,
5657 arraysize(valid_float_vec3_types_list),
5658};
5659
5660static const GLES2DecoderImpl::BaseUniformInfo valid_float_vec4_base_info = {
5661 valid_float_vec4_types_list,
5662 arraysize(valid_float_vec4_types_list),
5663};
5664
5665static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat2_base_info = {
5666 valid_float_mat2_types_list,
5667 arraysize(valid_float_mat2_types_list),
5668};
5669
5670static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat3_base_info = {
5671 valid_float_mat3_types_list,
5672 arraysize(valid_float_mat3_types_list),
5673};
5674
5675static const GLES2DecoderImpl::BaseUniformInfo valid_float_mat4_base_info = {
5676 valid_float_mat4_types_list,
5677 arraysize(valid_float_mat4_types_list),
5678};
5679
5680} // anonymous namespace.
5681
[email protected]43c2f1f2011-03-25 18:35:365682bool GLES2DecoderImpl::PrepForSetUniformByLocation(
[email protected]1b0a6752012-02-22 03:44:125683 GLint fake_location, const char* function_name,
[email protected]476ccb72012-12-06 15:52:525684 const GLES2DecoderImpl::BaseUniformInfo& base_info,
[email protected]1b0a6752012-02-22 03:44:125685 GLint* real_location, GLenum* type, GLsizei* count) {
[email protected]43c2f1f2011-03-25 18:35:365686 DCHECK(type);
5687 DCHECK(count);
[email protected]1b0a6752012-02-22 03:44:125688 DCHECK(real_location);
[email protected]476ccb72012-12-06 15:52:525689
[email protected]1b0a6752012-02-22 03:44:125690 if (!CheckCurrentProgramForUniform(fake_location, function_name)) {
[email protected]939e7362010-05-13 20:49:105691 return false;
5692 }
[email protected]43c2f1f2011-03-25 18:35:365693 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:355694 const Program::UniformInfo* info =
[email protected]e259eb412012-10-13 05:47:245695 state_.current_program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:125696 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:365697 if (!info) {
[email protected]ab09b612013-03-11 22:11:515698 LOCAL_SET_GL_ERROR(
5699 GL_INVALID_OPERATION, function_name, "unknown location");
[email protected]939e7362010-05-13 20:49:105700 return false;
5701 }
[email protected]476ccb72012-12-06 15:52:525702 bool okay = false;
5703 for (size_t ii = 0; ii < base_info.num_valid_types; ++ii) {
5704 if (base_info.valid_types[ii] == info->type) {
5705 okay = true;
5706 break;
5707 }
5708 }
5709 if (!okay) {
[email protected]ab09b612013-03-11 22:11:515710 LOCAL_SET_GL_ERROR(
5711 GL_INVALID_OPERATION, function_name,
5712 "wrong uniform function for type");
[email protected]476ccb72012-12-06 15:52:525713 return false;
5714 }
[email protected]43c2f1f2011-03-25 18:35:365715 if (*count > 1 && !info->is_array) {
[email protected]ab09b612013-03-11 22:11:515716 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:435717 GL_INVALID_OPERATION, function_name, "count > 1 for non-array");
[email protected]43c2f1f2011-03-25 18:35:365718 return false;
5719 }
5720 *count = std::min(info->size - array_index, *count);
5721 if (*count <= 0) {
5722 return false;
5723 }
5724 *type = info->type;
[email protected]939e7362010-05-13 20:49:105725 return true;
5726}
5727
[email protected]1b0a6752012-02-22 03:44:125728void GLES2DecoderImpl::DoUniform1i(GLint fake_location, GLint v0) {
5729 GLenum type = 0;
5730 GLsizei count = 1;
5731 GLint real_location = -1;
5732 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525733 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5734 &real_location, &type, &count)) {
[email protected]3916c97e2010-02-25 03:20:505735 return;
5736 }
[email protected]e259eb412012-10-13 05:47:245737 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025738 state_.texture_units.size(), fake_location, 1, &v0)) {
[email protected]ab09b612013-03-11 22:11:515739 LOCAL_SET_GL_ERROR(
5740 GL_INVALID_VALUE, "glUniform1i", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465741 return;
5742 }
[email protected]1b0a6752012-02-22 03:44:125743 glUniform1i(real_location, v0);
[email protected]3916c97e2010-02-25 03:20:505744}
5745
5746void GLES2DecoderImpl::DoUniform1iv(
[email protected]1b0a6752012-02-22 03:44:125747 GLint fake_location, GLsizei count, const GLint *value) {
[email protected]43c2f1f2011-03-25 18:35:365748 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125749 GLint real_location = -1;
5750 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525751 fake_location, "glUniform1iv", valid_int_vec1_base_info,
5752 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365753 return;
5754 }
[email protected]74727112012-06-13 21:18:085755 if (type == GL_SAMPLER_2D || type == GL_SAMPLER_2D_RECT_ARB ||
5756 type == GL_SAMPLER_CUBE || type == GL_SAMPLER_EXTERNAL_OES) {
[email protected]e259eb412012-10-13 05:47:245757 if (!state_.current_program->SetSamplers(
[email protected]1868a342012-11-07 15:56:025758 state_.texture_units.size(), fake_location, count, value)) {
[email protected]ab09b612013-03-11 22:11:515759 LOCAL_SET_GL_ERROR(
5760 GL_INVALID_VALUE, "glUniform1iv", "texture unit out of range");
[email protected]d20a6512012-05-02 20:17:465761 return;
5762 }
[email protected]43c2f1f2011-03-25 18:35:365763 }
[email protected]1b0a6752012-02-22 03:44:125764 glUniform1iv(real_location, count, value);
[email protected]3916c97e2010-02-25 03:20:505765}
5766
[email protected]939e7362010-05-13 20:49:105767void GLES2DecoderImpl::DoUniform1fv(
[email protected]1b0a6752012-02-22 03:44:125768 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365769 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125770 GLint real_location = -1;
5771 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525772 fake_location, "glUniform1fv", valid_float_vec1_base_info,
5773 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105774 return;
5775 }
5776 if (type == GL_BOOL) {
[email protected]40d90a22013-04-09 03:39:555777 scoped_ptr<GLint[]> temp(new GLint[count]);
[email protected]939e7362010-05-13 20:49:105778 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]136a63e2010-11-12 22:01:535779 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105780 }
[email protected]1b0a6752012-02-22 03:44:125781 DoUniform1iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105782 } else {
[email protected]1b0a6752012-02-22 03:44:125783 glUniform1fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105784 }
5785}
5786
5787void GLES2DecoderImpl::DoUniform2fv(
[email protected]1b0a6752012-02-22 03:44:125788 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365789 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125790 GLint real_location = -1;
5791 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525792 fake_location, "glUniform2fv", valid_float_vec2_base_info,
5793 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105794 return;
5795 }
5796 if (type == GL_BOOL_VEC2) {
5797 GLsizei num_values = count * 2;
[email protected]40d90a22013-04-09 03:39:555798 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105799 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535800 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105801 }
[email protected]1b0a6752012-02-22 03:44:125802 glUniform2iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105803 } else {
[email protected]1b0a6752012-02-22 03:44:125804 glUniform2fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105805 }
5806}
5807
5808void GLES2DecoderImpl::DoUniform3fv(
[email protected]1b0a6752012-02-22 03:44:125809 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365810 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125811 GLint real_location = -1;
5812 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525813 fake_location, "glUniform3fv", valid_float_vec3_base_info,
5814 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105815 return;
5816 }
5817 if (type == GL_BOOL_VEC3) {
5818 GLsizei num_values = count * 3;
[email protected]40d90a22013-04-09 03:39:555819 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105820 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535821 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105822 }
[email protected]1b0a6752012-02-22 03:44:125823 glUniform3iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105824 } else {
[email protected]1b0a6752012-02-22 03:44:125825 glUniform3fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105826 }
5827}
5828
5829void GLES2DecoderImpl::DoUniform4fv(
[email protected]1b0a6752012-02-22 03:44:125830 GLint fake_location, GLsizei count, const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365831 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125832 GLint real_location = -1;
5833 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525834 fake_location, "glUniform4fv", valid_float_vec4_base_info,
5835 &real_location, &type, &count)) {
[email protected]939e7362010-05-13 20:49:105836 return;
5837 }
5838 if (type == GL_BOOL_VEC4) {
5839 GLsizei num_values = count * 4;
[email protected]40d90a22013-04-09 03:39:555840 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]939e7362010-05-13 20:49:105841 for (GLsizei ii = 0; ii < num_values; ++ii) {
[email protected]136a63e2010-11-12 22:01:535842 temp[ii] = static_cast<GLint>(value[ii] != 0.0f);
[email protected]939e7362010-05-13 20:49:105843 }
[email protected]1b0a6752012-02-22 03:44:125844 glUniform4iv(real_location, count, temp.get());
[email protected]939e7362010-05-13 20:49:105845 } else {
[email protected]1b0a6752012-02-22 03:44:125846 glUniform4fv(real_location, count, value);
[email protected]939e7362010-05-13 20:49:105847 }
5848}
5849
[email protected]43c2f1f2011-03-25 18:35:365850void GLES2DecoderImpl::DoUniform2iv(
[email protected]1b0a6752012-02-22 03:44:125851 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365852 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125853 GLint real_location = -1;
5854 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525855 fake_location, "glUniform2iv", valid_int_vec2_base_info,
5856 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365857 return;
5858 }
[email protected]1b0a6752012-02-22 03:44:125859 glUniform2iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365860}
5861
5862void GLES2DecoderImpl::DoUniform3iv(
[email protected]1b0a6752012-02-22 03:44:125863 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365864 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125865 GLint real_location = -1;
5866 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525867 fake_location, "glUniform3iv", valid_int_vec3_base_info,
5868 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365869 return;
5870 }
[email protected]1b0a6752012-02-22 03:44:125871 glUniform3iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365872}
5873
5874void GLES2DecoderImpl::DoUniform4iv(
[email protected]1b0a6752012-02-22 03:44:125875 GLint fake_location, GLsizei count, const GLint* value) {
[email protected]43c2f1f2011-03-25 18:35:365876 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125877 GLint real_location = -1;
5878 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525879 fake_location, "glUniform4iv", valid_int_vec4_base_info,
5880 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365881 return;
5882 }
[email protected]1b0a6752012-02-22 03:44:125883 glUniform4iv(real_location, count, value);
[email protected]43c2f1f2011-03-25 18:35:365884}
5885
5886void GLES2DecoderImpl::DoUniformMatrix2fv(
[email protected]1b0a6752012-02-22 03:44:125887 GLint fake_location, GLsizei count, GLboolean transpose,
5888 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365889 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125890 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365891 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525892 fake_location, "glUniformMatrix2fv", valid_float_mat2_base_info,
5893 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365894 return;
5895 }
[email protected]1b0a6752012-02-22 03:44:125896 glUniformMatrix2fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365897}
5898
5899void GLES2DecoderImpl::DoUniformMatrix3fv(
[email protected]1b0a6752012-02-22 03:44:125900 GLint fake_location, GLsizei count, GLboolean transpose,
5901 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365902 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125903 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365904 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525905 fake_location, "glUniformMatrix3fv", valid_float_mat3_base_info,
5906 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365907 return;
5908 }
[email protected]1b0a6752012-02-22 03:44:125909 glUniformMatrix3fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365910}
5911
5912void GLES2DecoderImpl::DoUniformMatrix4fv(
[email protected]1b0a6752012-02-22 03:44:125913 GLint fake_location, GLsizei count, GLboolean transpose,
5914 const GLfloat* value) {
[email protected]43c2f1f2011-03-25 18:35:365915 GLenum type = 0;
[email protected]1b0a6752012-02-22 03:44:125916 GLint real_location = -1;
[email protected]43c2f1f2011-03-25 18:35:365917 if (!PrepForSetUniformByLocation(
[email protected]476ccb72012-12-06 15:52:525918 fake_location, "glUniformMatrix4fv", valid_float_mat4_base_info,
5919 &real_location, &type, &count)) {
[email protected]43c2f1f2011-03-25 18:35:365920 return;
5921 }
[email protected]1b0a6752012-02-22 03:44:125922 glUniformMatrix4fv(real_location, count, transpose, value);
[email protected]43c2f1f2011-03-25 18:35:365923}
5924
[email protected]df37b9932013-03-08 05:21:425925void GLES2DecoderImpl::DoUseProgram(GLuint program_id) {
[email protected]ae51d192010-04-27 00:48:035926 GLuint service_id = 0;
[email protected]df37b9932013-03-08 05:21:425927 Program* program = NULL;
5928 if (program_id) {
5929 program = GetProgramInfoNotShader(program_id, "glUseProgram");
5930 if (!program) {
[email protected]ae51d192010-04-27 00:48:035931 return;
5932 }
[email protected]df37b9932013-03-08 05:21:425933 if (!program->IsValid()) {
[email protected]3916c97e2010-02-25 03:20:505934 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:515935 LOCAL_SET_GL_ERROR(
5936 GL_INVALID_OPERATION, "glUseProgram", "program not linked");
[email protected]3916c97e2010-02-25 03:20:505937 return;
5938 }
[email protected]df37b9932013-03-08 05:21:425939 service_id = program->service_id();
[email protected]3916c97e2010-02-25 03:20:505940 }
[email protected]7cd76fd2013-06-02 21:11:115941 if (state_.current_program.get()) {
5942 program_manager()->UnuseProgram(shader_manager(),
5943 state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:145944 }
[email protected]df37b9932013-03-08 05:21:425945 state_.current_program = program;
5946 LogClientServiceMapping("glUseProgram", program_id, service_id);
[email protected]2df73892012-04-28 01:09:545947 glUseProgram(service_id);
[email protected]7cd76fd2013-06-02 21:11:115948 if (state_.current_program.get()) {
5949 program_manager()->UseProgram(state_.current_program.get());
[email protected]ca488e12010-12-13 20:06:145950 }
[email protected]3916c97e2010-02-25 03:20:505951}
5952
[email protected]ab09b612013-03-11 22:11:515953void GLES2DecoderImpl::RenderWarning(
5954 const char* filename, int line, const std::string& msg) {
[email protected]1d82e822013-04-10 21:32:325955 logger_.LogMessage(filename, line, std::string("RENDER WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015956}
5957
[email protected]ab09b612013-03-11 22:11:515958void GLES2DecoderImpl::PerformanceWarning(
5959 const char* filename, int line, const std::string& msg) {
[email protected]d3eba342013-04-18 21:11:505960 logger_.LogMessage(filename, line,
5961 std::string("PERFORMANCE WARNING: ") + msg);
[email protected]0f8afe82012-05-14 23:43:015962}
5963
[email protected]e8dc5662013-10-17 23:28:295964void GLES2DecoderImpl::UpdateStreamTextureIfNeeded(Texture* texture,
5965 GLuint texture_unit_index) {
[email protected]e56131d22013-07-28 16:14:115966 if (texture && texture->IsStreamTexture()) {
5967 DCHECK(stream_texture_manager());
5968 StreamTexture* stream_tex =
5969 stream_texture_manager()->LookupStreamTexture(texture->service_id());
[email protected]e8dc5662013-10-17 23:28:295970 if (stream_tex) {
5971 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]e56131d22013-07-28 16:14:115972 stream_tex->Update();
[email protected]e8dc5662013-10-17 23:28:295973 }
[email protected]e56131d22013-07-28 16:14:115974 }
5975}
5976
[email protected]91c94eb2013-10-22 10:32:545977void GLES2DecoderImpl::DoWillUseTexImageIfNeeded(
5978 Texture* texture, GLenum textarget) {
5979 // This might be supported in the future.
5980 if (textarget != GL_TEXTURE_2D)
5981 return;
5982 // Image is already in use if texture is attached to a framebuffer.
5983 if (texture && !texture->IsAttachedToFramebuffer()) {
5984 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
5985 if (image) {
5986 ScopedGLErrorSuppressor suppressor(
5987 "GLES2DecoderImpl::DoWillUseTexImageIfNeeded",
5988 GetErrorState());
5989 glBindTexture(textarget, texture->service_id());
5990 image->WillUseTexImage();
[email protected]ce296892013-10-24 22:04:365991 RestoreCurrentTexture2DBindings(&state_);
[email protected]91c94eb2013-10-22 10:32:545992 }
5993 }
5994}
5995
5996void GLES2DecoderImpl::DoDidUseTexImageIfNeeded(
5997 Texture* texture, GLenum textarget) {
5998 // This might be supported in the future.
5999 if (textarget != GL_TEXTURE_2D)
6000 return;
6001 // Image is still in use if texture is attached to a framebuffer.
6002 if (texture && !texture->IsAttachedToFramebuffer()) {
6003 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6004 if (image) {
6005 ScopedGLErrorSuppressor suppressor(
6006 "GLES2DecoderImpl::DoDidUseTexImageIfNeeded",
6007 GetErrorState());
6008 glBindTexture(textarget, texture->service_id());
6009 image->DidUseTexImage();
[email protected]ce296892013-10-24 22:04:366010 RestoreCurrentTexture2DBindings(&state_);
[email protected]91c94eb2013-10-22 10:32:546011 }
6012 }
6013}
6014
[email protected]e56131d22013-07-28 16:14:116015bool GLES2DecoderImpl::PrepareTexturesForRender() {
[email protected]7cd76fd2013-06-02 21:11:116016 DCHECK(state_.current_program.get());
[email protected]91c94eb2013-10-22 10:32:546017 if (!texture_manager()->HaveUnrenderableTextures() &&
6018 !texture_manager()->HaveImages() &&
6019 !features().oes_egl_image_external) {
[email protected]e56131d22013-07-28 16:14:116020 return true;
[email protected]ef526492010-06-02 23:12:256021 }
[email protected]e2367b42013-05-31 03:37:216022
[email protected]ef526492010-06-02 23:12:256023 bool textures_set = false;
[email protected]ed9f9cd2013-02-27 21:12:356024 const Program::SamplerIndices& sampler_indices =
[email protected]e259eb412012-10-13 05:47:246025 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506026 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356027 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246028 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506029 DCHECK(uniform_info);
6030 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6031 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026032 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246033 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]91c94eb2013-10-22 10:32:546034 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366035 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]91c94eb2013-10-22 10:32:546036 GLenum textarget = GetBindTargetForSamplerType(uniform_info->type);
6037 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]ef526492010-06-02 23:12:256038 textures_set = true;
[email protected]3916c97e2010-02-25 03:20:506039 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6040 glBindTexture(
[email protected]91c94eb2013-10-22 10:32:546041 textarget,
[email protected]00f893d2010-08-24 18:55:496042 texture_manager()->black_texture_id(uniform_info->type));
[email protected]ab09b612013-03-11 22:11:516043 LOCAL_RENDER_WARNING(
[email protected]0f8afe82012-05-14 23:43:016044 std::string("texture bound to texture unit ") +
6045 base::IntToString(texture_unit_index) +
[email protected]ad9b7f8b2013-06-17 07:36:296046 " is not renderable. It maybe non-power-of-2 and have"
6047 " incompatible texture filtering or is not"
6048 " 'texture complete'");
[email protected]91c94eb2013-10-22 10:32:546049 continue;
[email protected]3916c97e2010-02-25 03:20:506050 }
[email protected]91c94eb2013-10-22 10:32:546051
6052 Texture* texture = texture_ref->texture();
6053 if (textarget == GL_TEXTURE_2D) {
6054 gfx::GLImage* image = texture->GetLevelImage(textarget, 0);
6055 if (image && !texture->IsAttachedToFramebuffer()) {
6056 ScopedGLErrorSuppressor suppressor(
6057 "GLES2DecoderImpl::PrepareTexturesForRender", GetErrorState());
6058 textures_set = true;
6059 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6060 image->WillUseTexImage();
6061 continue;
6062 }
6063 }
6064
6065 UpdateStreamTextureIfNeeded(texture, texture_unit_index);
[email protected]3916c97e2010-02-25 03:20:506066 }
6067 // else: should this be an error?
6068 }
6069 }
[email protected]e56131d22013-07-28 16:14:116070 return !textures_set;
[email protected]3916c97e2010-02-25 03:20:506071}
6072
[email protected]91c94eb2013-10-22 10:32:546073void GLES2DecoderImpl::RestoreStateForTextures() {
[email protected]7cd76fd2013-06-02 21:11:116074 DCHECK(state_.current_program.get());
[email protected]ed9f9cd2013-02-27 21:12:356075 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116076 state_.current_program->sampler_indices();
[email protected]3916c97e2010-02-25 03:20:506077 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356078 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246079 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]3916c97e2010-02-25 03:20:506080 DCHECK(uniform_info);
6081 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6082 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026083 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246084 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]7cd76fd2013-06-02 21:11:116085 TextureRef* texture_ref =
[email protected]91c94eb2013-10-22 10:32:546086 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496087 if (!texture_ref || !texture_manager()->CanRender(texture_ref)) {
[email protected]3916c97e2010-02-25 03:20:506088 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
[email protected]370eaf12013-05-18 09:19:496089 // Get the texture_ref info that was previously bound here.
[email protected]7cd76fd2013-06-02 21:11:116090 texture_ref = texture_unit.bind_target == GL_TEXTURE_2D
6091 ? texture_unit.bound_texture_2d.get()
6092 : texture_unit.bound_texture_cube_map.get();
[email protected]3916c97e2010-02-25 03:20:506093 glBindTexture(texture_unit.bind_target,
[email protected]370eaf12013-05-18 09:19:496094 texture_ref ? texture_ref->service_id() : 0);
[email protected]91c94eb2013-10-22 10:32:546095 continue;
6096 }
6097
6098 Texture* texture = texture_ref->texture();
6099 if (texture_unit.bind_target == GL_TEXTURE_2D) {
6100 gfx::GLImage* image = texture->GetLevelImage(
6101 texture_unit.bind_target, 0);
6102 if (image && !texture->IsAttachedToFramebuffer()) {
6103 ScopedGLErrorSuppressor suppressor(
6104 "GLES2DecoderImpl::RestoreStateForTextures", GetErrorState());
6105 glActiveTexture(GL_TEXTURE0 + texture_unit_index);
6106 image->DidUseTexImage();
6107 continue;
6108 }
[email protected]3916c97e2010-02-25 03:20:506109 }
6110 }
6111 }
6112 }
6113 // Set the active texture back to whatever the user had it as.
[email protected]e259eb412012-10-13 05:47:246114 glActiveTexture(GL_TEXTURE0 + state_.active_texture_unit);
[email protected]07f54fcc2009-12-22 02:46:306115}
6116
[email protected]0d6bfdc2011-11-02 01:32:206117bool GLES2DecoderImpl::ClearUnclearedTextures() {
6118 // Only check if there are some uncleared textures.
6119 if (!texture_manager()->HaveUnsafeTextures()) {
6120 return true;
6121 }
6122
6123 // 1: Check all textures we are about to render with.
[email protected]7cd76fd2013-06-02 21:11:116124 if (state_.current_program.get()) {
[email protected]ed9f9cd2013-02-27 21:12:356125 const Program::SamplerIndices& sampler_indices =
[email protected]7cd76fd2013-06-02 21:11:116126 state_.current_program->sampler_indices();
[email protected]0d6bfdc2011-11-02 01:32:206127 for (size_t ii = 0; ii < sampler_indices.size(); ++ii) {
[email protected]ed9f9cd2013-02-27 21:12:356128 const Program::UniformInfo* uniform_info =
[email protected]e259eb412012-10-13 05:47:246129 state_.current_program->GetUniformInfo(sampler_indices[ii]);
[email protected]0d6bfdc2011-11-02 01:32:206130 DCHECK(uniform_info);
6131 for (size_t jj = 0; jj < uniform_info->texture_units.size(); ++jj) {
6132 GLuint texture_unit_index = uniform_info->texture_units[jj];
[email protected]1868a342012-11-07 15:56:026133 if (texture_unit_index < state_.texture_units.size()) {
[email protected]e259eb412012-10-13 05:47:246134 TextureUnit& texture_unit = state_.texture_units[texture_unit_index];
[email protected]370eaf12013-05-18 09:19:496135 TextureRef* texture_ref =
[email protected]cadac622013-06-11 16:46:366136 texture_unit.GetInfoForSamplerType(uniform_info->type).get();
[email protected]370eaf12013-05-18 09:19:496137 if (texture_ref && !texture_ref->texture()->SafeToRenderFrom()) {
6138 if (!texture_manager()->ClearRenderableLevels(this, texture_ref)) {
[email protected]0d6bfdc2011-11-02 01:32:206139 return false;
6140 }
6141 }
6142 }
6143 }
6144 }
6145 }
6146 return true;
6147}
6148
[email protected]c6aef902012-02-14 03:31:426149bool GLES2DecoderImpl::IsDrawValid(
[email protected]ad84a3a2012-06-08 21:42:436150 const char* function_name, GLuint max_vertex_accessed, GLsizei primcount) {
[email protected]689fa1c52010-06-09 18:35:036151 // NOTE: We specifically do not check current_program->IsValid() because
6152 // it could never be invalid since glUseProgram would have failed. While
6153 // glLinkProgram could later mark the program as invalid the previous
6154 // valid program will still function if it is still the current program.
[email protected]7cd76fd2013-06-02 21:11:116155 if (!state_.current_program.get()) {
[email protected]3916c97e2010-02-25 03:20:506156 // The program does not exist.
6157 // But GL says no ERROR.
[email protected]ab09b612013-03-11 22:11:516158 LOCAL_RENDER_WARNING("Drawing with no current shader program.");
[email protected]3916c97e2010-02-25 03:20:506159 return false;
6160 }
[email protected]c6aef902012-02-14 03:31:426161
[email protected]7cd76fd2013-06-02 21:11:116162 return state_.vertex_attrib_manager
6163 ->ValidateBindings(function_name,
6164 this,
6165 feature_info_.get(),
6166 state_.current_program.get(),
6167 max_vertex_accessed,
6168 primcount);
[email protected]b1122982010-05-17 23:04:246169}
6170
[email protected]c13e1da62011-09-09 21:48:306171bool GLES2DecoderImpl::SimulateAttrib0(
[email protected]ad84a3a2012-06-08 21:42:436172 const char* function_name, GLuint max_vertex_accessed, bool* simulated) {
[email protected]c13e1da62011-09-09 21:48:306173 DCHECK(simulated);
6174 *simulated = false;
6175
[email protected]876f6fee2010-08-02 23:10:326176 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
[email protected]c13e1da62011-09-09 21:48:306177 return true;
[email protected]876f6fee2010-08-02 23:10:326178
[email protected]ac77603c72013-03-08 13:52:066179 const VertexAttrib* attrib =
[email protected]ed9f9cd2013-02-27 21:12:356180 state_.vertex_attrib_manager->GetVertexAttrib(0);
[email protected]b1122982010-05-17 23:04:246181 // If it's enabled or it's not used then we don't need to do anything.
[email protected]e259eb412012-10-13 05:47:246182 bool attrib_0_used =
6183 state_.current_program->GetAttribInfoByLocation(0) != NULL;
[email protected]ac77603c72013-03-08 13:52:066184 if (attrib->enabled() && attrib_0_used) {
[email protected]c13e1da62011-09-09 21:48:306185 return true;
[email protected]b1122982010-05-17 23:04:246186 }
6187
[email protected]b1122982010-05-17 23:04:246188 // Make a buffer with a single repeated vec4 value enough to
6189 // simulate the constant value that is supposed to be here.
6190 // This is required to emulate GLES2 on GL.
[email protected]c13e1da62011-09-09 21:48:306191 GLuint num_vertices = max_vertex_accessed + 1;
[email protected]3aad1a32012-09-07 20:54:476192 uint32 size_needed = 0;
[email protected]c13e1da62011-09-09 21:48:306193
6194 if (num_vertices == 0 ||
[email protected]3aad1a32012-09-07 20:54:476195 !SafeMultiplyUint32(num_vertices, sizeof(Vec4), &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306196 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516197 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306198 return false;
6199 }
6200
[email protected]ab09b612013-03-11 22:11:516201 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016202 "Attribute 0 is disabled. This has signficant performance penalty");
6203
[email protected]ab09b612013-03-11 22:11:516204 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]c13e1da62011-09-09 21:48:306205 glBindBuffer(GL_ARRAY_BUFFER, attrib_0_buffer_id_);
6206
[email protected]8f0b86c2f2012-04-10 05:48:286207 bool new_buffer = static_cast<GLsizei>(size_needed) > attrib_0_size_;
6208 if (new_buffer) {
[email protected]fc753442011-02-04 19:49:496209 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306210 GLenum error = glGetError();
6211 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516212 LOCAL_SET_GL_ERROR(
6213 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c13e1da62011-09-09 21:48:306214 return false;
6215 }
[email protected]fc753442011-02-04 19:49:496216 }
[email protected]af6380962012-11-29 23:24:136217
6218 const Vec4& value = state_.attrib_values[0];
[email protected]8f0b86c2f2012-04-10 05:48:286219 if (new_buffer ||
6220 (attrib_0_used &&
6221 (!attrib_0_buffer_matches_value_ ||
[email protected]af6380962012-11-29 23:24:136222 (value.v[0] != attrib_0_value_.v[0] ||
6223 value.v[1] != attrib_0_value_.v[1] ||
6224 value.v[2] != attrib_0_value_.v[2] ||
6225 value.v[3] != attrib_0_value_.v[3])))) {
6226 std::vector<Vec4> temp(num_vertices, value);
[email protected]fc753442011-02-04 19:49:496227 glBufferSubData(GL_ARRAY_BUFFER, 0, size_needed, &temp[0].v[0]);
6228 attrib_0_buffer_matches_value_ = true;
[email protected]af6380962012-11-29 23:24:136229 attrib_0_value_ = value;
[email protected]b1122982010-05-17 23:04:246230 attrib_0_size_ = size_needed;
6231 }
6232
6233 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);
6234
[email protected]ac77603c72013-03-08 13:52:066235 if (attrib->divisor())
[email protected]c6aef902012-02-14 03:31:426236 glVertexAttribDivisorANGLE(0, 0);
6237
[email protected]c13e1da62011-09-09 21:48:306238 *simulated = true;
[email protected]b1122982010-05-17 23:04:246239 return true;
[email protected]b1122982010-05-17 23:04:246240}
6241
[email protected]ac77603c72013-03-08 13:52:066242void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib_index) {
6243 const VertexAttrib* attrib =
6244 state_.vertex_attrib_manager->GetVertexAttrib(attrib_index);
6245 const void* ptr = reinterpret_cast<const void*>(attrib->offset());
6246 Buffer* buffer = attrib->buffer();
[email protected]b10492f2013-03-08 05:24:076247 glBindBuffer(GL_ARRAY_BUFFER, buffer ? buffer->service_id() : 0);
[email protected]b1122982010-05-17 23:04:246248 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066249 attrib_index, attrib->size(), attrib->type(), attrib->normalized(),
6250 attrib->gl_stride(), ptr);
6251 if (attrib->divisor())
6252 glVertexAttribDivisorANGLE(attrib_index, attrib->divisor());
[email protected]e259eb412012-10-13 05:47:246253 glBindBuffer(
6254 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116255 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6256 : 0);
[email protected]43410e92012-04-20 17:06:286257
[email protected]265f8992012-07-20 01:03:146258 // Never touch vertex attribute 0's state (in particular, never
6259 // disable it) when running on desktop GL because it will never be
6260 // re-enabled.
[email protected]ac77603c72013-03-08 13:52:066261 if (attrib_index != 0 ||
[email protected]265f8992012-07-20 01:03:146262 gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) {
[email protected]ac77603c72013-03-08 13:52:066263 if (attrib->enabled()) {
6264 glEnableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146265 } else {
[email protected]ac77603c72013-03-08 13:52:066266 glDisableVertexAttribArray(attrib_index);
[email protected]265f8992012-07-20 01:03:146267 }
[email protected]43410e92012-04-20 17:06:286268 }
[email protected]b1122982010-05-17 23:04:246269}
[email protected]07f54fcc2009-12-22 02:46:306270
[email protected]8fbedc02010-11-18 18:43:406271bool GLES2DecoderImpl::SimulateFixedAttribs(
[email protected]ad84a3a2012-06-08 21:42:436272 const char* function_name,
[email protected]c6aef902012-02-14 03:31:426273 GLuint max_vertex_accessed, bool* simulated, GLsizei primcount) {
[email protected]8fbedc02010-11-18 18:43:406274 DCHECK(simulated);
6275 *simulated = false;
6276 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2)
6277 return true;
6278
[email protected]e259eb412012-10-13 05:47:246279 if (!state_.vertex_attrib_manager->HaveFixedAttribs()) {
[email protected]8fbedc02010-11-18 18:43:406280 return true;
6281 }
6282
[email protected]ab09b612013-03-11 22:11:516283 LOCAL_PERFORMANCE_WARNING(
[email protected]0f8afe82012-05-14 23:43:016284 "GL_FIXED attributes have a signficant performance penalty");
6285
[email protected]8fbedc02010-11-18 18:43:406286 // NOTE: we could be smart and try to check if a buffer is used
6287 // twice in 2 different attribs, find the overlapping parts and therefore
6288 // duplicate the minimum amount of data but this whole code path is not meant
6289 // to be used normally. It's just here to pass that OpenGL ES 2.0 conformance
6290 // tests so we just add to the buffer attrib used.
6291
[email protected]c13e1da62011-09-09 21:48:306292 GLuint elements_needed = 0;
[email protected]ac77603c72013-03-08 13:52:066293 const VertexAttribManager::VertexAttribList& enabled_attribs =
6294 state_.vertex_attrib_manager->GetEnabledVertexAttribs();
6295 for (VertexAttribManager::VertexAttribList::const_iterator it =
6296 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6297 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356298 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066299 state_.current_program->GetAttribInfoByLocation(attrib->index());
6300 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
6301 max_vertex_accessed);
[email protected]c6aef902012-02-14 03:31:426302 GLuint num_vertices = max_accessed + 1;
6303 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516304 LOCAL_SET_GL_ERROR(
6305 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426306 return false;
6307 }
[email protected]8fbedc02010-11-18 18:43:406308 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066309 attrib->CanAccess(max_accessed) &&
6310 attrib->type() == GL_FIXED) {
[email protected]3aad1a32012-09-07 20:54:476311 uint32 elements_used = 0;
[email protected]ac77603c72013-03-08 13:52:066312 if (!SafeMultiplyUint32(num_vertices, attrib->size(), &elements_used) ||
[email protected]3aad1a32012-09-07 20:54:476313 !SafeAddUint32(elements_needed, elements_used, &elements_needed)) {
[email protected]ab09b612013-03-11 22:11:516314 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436315 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406316 return false;
6317 }
6318 }
6319 }
6320
[email protected]3aad1a32012-09-07 20:54:476321 const uint32 kSizeOfFloat = sizeof(float); // NOLINT
6322 uint32 size_needed = 0;
6323 if (!SafeMultiplyUint32(elements_needed, kSizeOfFloat, &size_needed) ||
[email protected]c13e1da62011-09-09 21:48:306324 size_needed > 0x7FFFFFFFU) {
[email protected]ab09b612013-03-11 22:11:516325 LOCAL_SET_GL_ERROR(
6326 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]8fbedc02010-11-18 18:43:406327 return false;
6328 }
6329
[email protected]ab09b612013-03-11 22:11:516330 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name);
[email protected]8fbedc02010-11-18 18:43:406331
6332 glBindBuffer(GL_ARRAY_BUFFER, fixed_attrib_buffer_id_);
[email protected]c13e1da62011-09-09 21:48:306333 if (static_cast<GLsizei>(size_needed) > fixed_attrib_buffer_size_) {
[email protected]8fbedc02010-11-18 18:43:406334 glBufferData(GL_ARRAY_BUFFER, size_needed, NULL, GL_DYNAMIC_DRAW);
[email protected]c13e1da62011-09-09 21:48:306335 GLenum error = glGetError();
6336 if (error != GL_NO_ERROR) {
[email protected]ab09b612013-03-11 22:11:516337 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:436338 GL_OUT_OF_MEMORY, function_name, "simulating GL_FIXED attribs");
[email protected]c13e1da62011-09-09 21:48:306339 return false;
6340 }
[email protected]8fbedc02010-11-18 18:43:406341 }
6342
6343 // Copy the elements and convert to float
6344 GLintptr offset = 0;
[email protected]ac77603c72013-03-08 13:52:066345 for (VertexAttribManager::VertexAttribList::const_iterator it =
6346 enabled_attribs.begin(); it != enabled_attribs.end(); ++it) {
6347 const VertexAttrib* attrib = *it;
[email protected]ed9f9cd2013-02-27 21:12:356348 const Program::VertexAttrib* attrib_info =
[email protected]ac77603c72013-03-08 13:52:066349 state_.current_program->GetAttribInfoByLocation(attrib->index());
6350 GLuint max_accessed = attrib->MaxVertexAccessed(primcount,
[email protected]c6aef902012-02-14 03:31:426351 max_vertex_accessed);
6352 GLuint num_vertices = max_accessed + 1;
6353 if (num_vertices == 0) {
[email protected]ab09b612013-03-11 22:11:516354 LOCAL_SET_GL_ERROR(
6355 GL_OUT_OF_MEMORY, function_name, "Simulating attrib 0");
[email protected]c6aef902012-02-14 03:31:426356 return false;
6357 }
[email protected]8fbedc02010-11-18 18:43:406358 if (attrib_info &&
[email protected]ac77603c72013-03-08 13:52:066359 attrib->CanAccess(max_accessed) &&
6360 attrib->type() == GL_FIXED) {
6361 int num_elements = attrib->size() * kSizeOfFloat;
[email protected]8fbedc02010-11-18 18:43:406362 int size = num_elements * num_vertices;
[email protected]40d90a22013-04-09 03:39:556363 scoped_ptr<float[]> data(new float[size]);
[email protected]8fbedc02010-11-18 18:43:406364 const int32* src = reinterpret_cast<const int32 *>(
[email protected]ac77603c72013-03-08 13:52:066365 attrib->buffer()->GetRange(attrib->offset(), size));
[email protected]8fbedc02010-11-18 18:43:406366 const int32* end = src + num_elements;
6367 float* dst = data.get();
6368 while (src != end) {
6369 *dst++ = static_cast<float>(*src++) / 65536.0f;
6370 }
6371 glBufferSubData(GL_ARRAY_BUFFER, offset, size, data.get());
6372 glVertexAttribPointer(
[email protected]ac77603c72013-03-08 13:52:066373 attrib->index(), attrib->size(), GL_FLOAT, false, 0,
[email protected]8fbedc02010-11-18 18:43:406374 reinterpret_cast<GLvoid*>(offset));
6375 offset += size;
6376 }
6377 }
6378 *simulated = true;
6379 return true;
6380}
6381
6382void GLES2DecoderImpl::RestoreStateForSimulatedFixedAttribs() {
6383 // There's no need to call glVertexAttribPointer because we shadow all the
6384 // settings and passing GL_FIXED to it will not work.
[email protected]e259eb412012-10-13 05:47:246385 glBindBuffer(
6386 GL_ARRAY_BUFFER,
[email protected]7cd76fd2013-06-02 21:11:116387 state_.bound_array_buffer.get() ? state_.bound_array_buffer->service_id()
6388 : 0);
[email protected]8fbedc02010-11-18 18:43:406389}
6390
[email protected]ad84a3a2012-06-08 21:42:436391error::Error GLES2DecoderImpl::DoDrawArrays(
6392 const char* function_name,
6393 bool instanced,
6394 GLenum mode,
6395 GLint first,
6396 GLsizei count,
6397 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226398 error::Error error = WillAccessBoundFramebufferForDraw();
6399 if (error != error::kNoError)
6400 return error;
[email protected]38d139d2011-07-14 00:38:436401 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516402 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]38d139d2011-07-14 00:38:436403 return error::kNoError;
6404 }
6405 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516406 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]38d139d2011-07-14 00:38:436407 return error::kNoError;
6408 }
[email protected]c6aef902012-02-14 03:31:426409 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516410 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426411 return error::kNoError;
6412 }
[email protected]ad84a3a2012-06-08 21:42:436413 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]38d139d2011-07-14 00:38:436414 return error::kNoError;
6415 }
6416 // We have to check this here because the prototype for glDrawArrays
6417 // is GLint not GLsizei.
6418 if (first < 0) {
[email protected]ab09b612013-03-11 22:11:516419 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "first < 0");
[email protected]38d139d2011-07-14 00:38:436420 return error::kNoError;
6421 }
6422
[email protected]c6aef902012-02-14 03:31:426423 if (count == 0 || (instanced && primcount == 0)) {
[email protected]ab09b612013-03-11 22:11:516424 LOCAL_RENDER_WARNING("Render count or primcount is 0.");
[email protected]38d139d2011-07-14 00:38:436425 return error::kNoError;
6426 }
6427
6428 GLuint max_vertex_accessed = first + count - 1;
[email protected]ad84a3a2012-06-08 21:42:436429 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206430 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516431 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206432 return error::kNoError;
6433 }
[email protected]c13e1da62011-09-09 21:48:306434 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436435 if (!SimulateAttrib0(
6436 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306437 return error::kNoError;
6438 }
[email protected]38d139d2011-07-14 00:38:436439 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436440 if (SimulateFixedAttribs(
6441 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6442 primcount)) {
[email protected]e56131d22013-07-28 16:14:116443 bool textures_set = !PrepareTexturesForRender();
[email protected]38d139d2011-07-14 00:38:436444 ApplyDirtyState();
[email protected]c6aef902012-02-14 03:31:426445 if (!instanced) {
6446 glDrawArrays(mode, first, count);
6447 } else {
6448 glDrawArraysInstancedANGLE(mode, first, count, primcount);
6449 }
[email protected]22e3f552012-03-13 01:54:196450 ProcessPendingQueries();
[email protected]38d139d2011-07-14 00:38:436451 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546452 RestoreStateForTextures();
[email protected]38d139d2011-07-14 00:38:436453 }
6454 if (simulated_fixed_attribs) {
6455 RestoreStateForSimulatedFixedAttribs();
6456 }
6457 }
6458 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286459 RestoreStateForAttrib(0);
[email protected]38d139d2011-07-14 00:38:436460 }
[email protected]38d139d2011-07-14 00:38:436461 }
6462 return error::kNoError;
6463}
6464
[email protected]c6aef902012-02-14 03:31:426465error::Error GLES2DecoderImpl::HandleDrawArrays(
[email protected]ed9f9cd2013-02-27 21:12:356466 uint32 immediate_data_size, const cmds::DrawArrays& c) {
[email protected]ad84a3a2012-06-08 21:42:436467 return DoDrawArrays("glDrawArrays",
6468 false,
[email protected]c6aef902012-02-14 03:31:426469 static_cast<GLenum>(c.mode),
6470 static_cast<GLint>(c.first),
6471 static_cast<GLsizei>(c.count),
6472 0);
6473}
6474
6475error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356476 uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156477 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516478 LOCAL_SET_GL_ERROR(
6479 GL_INVALID_OPERATION,
6480 "glDrawArraysInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426481 return error::kNoError;
6482 }
[email protected]ad84a3a2012-06-08 21:42:436483 return DoDrawArrays("glDrawArraysIntancedANGLE",
6484 true,
[email protected]c6aef902012-02-14 03:31:426485 static_cast<GLenum>(c.mode),
6486 static_cast<GLint>(c.first),
6487 static_cast<GLsizei>(c.count),
6488 static_cast<GLsizei>(c.primcount));
6489}
6490
[email protected]ad84a3a2012-06-08 21:42:436491error::Error GLES2DecoderImpl::DoDrawElements(
6492 const char* function_name,
6493 bool instanced,
6494 GLenum mode,
6495 GLsizei count,
6496 GLenum type,
6497 int32 offset,
6498 GLsizei primcount) {
[email protected]c76fe672013-12-13 23:30:226499 error::Error error = WillAccessBoundFramebufferForDraw();
6500 if (error != error::kNoError)
6501 return error;
[email protected]e259eb412012-10-13 05:47:246502 if (!state_.vertex_attrib_manager->element_array_buffer()) {
[email protected]ab09b612013-03-11 22:11:516503 LOCAL_SET_GL_ERROR(
6504 GL_INVALID_OPERATION, function_name, "No element array buffer bound");
[email protected]8eee29c2010-04-29 03:38:296505 return error::kNoError;
6506 }
6507
[email protected]8eee29c2010-04-29 03:38:296508 if (count < 0) {
[email protected]ab09b612013-03-11 22:11:516509 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "count < 0");
[email protected]8eee29c2010-04-29 03:38:296510 return error::kNoError;
6511 }
6512 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:516513 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "offset < 0");
[email protected]8eee29c2010-04-29 03:38:296514 return error::kNoError;
6515 }
[email protected]9438b012010-06-15 22:55:056516 if (!validators_->draw_mode.IsValid(mode)) {
[email protected]ab09b612013-03-11 22:11:516517 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, mode, "mode");
[email protected]8eee29c2010-04-29 03:38:296518 return error::kNoError;
6519 }
[email protected]9438b012010-06-15 22:55:056520 if (!validators_->index_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:516521 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]8eee29c2010-04-29 03:38:296522 return error::kNoError;
6523 }
[email protected]c6aef902012-02-14 03:31:426524 if (primcount < 0) {
[email protected]ab09b612013-03-11 22:11:516525 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "primcount < 0");
[email protected]c6aef902012-02-14 03:31:426526 return error::kNoError;
6527 }
[email protected]8eee29c2010-04-29 03:38:296528
[email protected]ad84a3a2012-06-08 21:42:436529 if (!CheckBoundFramebuffersValid(function_name)) {
[email protected]3a03a8f2011-03-19 00:51:276530 return error::kNoError;
6531 }
6532
[email protected]c6aef902012-02-14 03:31:426533 if (count == 0 || (instanced && primcount == 0)) {
[email protected]6c788fb72010-08-26 02:16:316534 return error::kNoError;
6535 }
6536
[email protected]8eee29c2010-04-29 03:38:296537 GLuint max_vertex_accessed;
[email protected]17cfbe0e2013-03-07 01:26:086538 Buffer* element_array_buffer =
6539 state_.vertex_attrib_manager->element_array_buffer();
6540
6541 if (!element_array_buffer->GetMaxValueForRange(
6542 offset, count, type, &max_vertex_accessed)) {
[email protected]ab09b612013-03-11 22:11:516543 LOCAL_SET_GL_ERROR(
6544 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer");
[email protected]8eee29c2010-04-29 03:38:296545 return error::kNoError;
6546 }
6547
[email protected]ad84a3a2012-06-08 21:42:436548 if (IsDrawValid(function_name, max_vertex_accessed, primcount)) {
[email protected]0d6bfdc2011-11-02 01:32:206549 if (!ClearUnclearedTextures()) {
[email protected]ab09b612013-03-11 22:11:516550 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory");
[email protected]0d6bfdc2011-11-02 01:32:206551 return error::kNoError;
6552 }
[email protected]c13e1da62011-09-09 21:48:306553 bool simulated_attrib_0 = false;
[email protected]ad84a3a2012-06-08 21:42:436554 if (!SimulateAttrib0(
6555 function_name, max_vertex_accessed, &simulated_attrib_0)) {
[email protected]c13e1da62011-09-09 21:48:306556 return error::kNoError;
6557 }
[email protected]8fbedc02010-11-18 18:43:406558 bool simulated_fixed_attribs = false;
[email protected]ad84a3a2012-06-08 21:42:436559 if (SimulateFixedAttribs(
6560 function_name, max_vertex_accessed, &simulated_fixed_attribs,
6561 primcount)) {
[email protected]e56131d22013-07-28 16:14:116562 bool textures_set = !PrepareTexturesForRender();
[email protected]297ca1c2011-06-20 23:08:466563 ApplyDirtyState();
[email protected]17cfbe0e2013-03-07 01:26:086564 // TODO(gman): Refactor to hide these details in BufferManager or
6565 // VertexAttribManager.
[email protected]8fbedc02010-11-18 18:43:406566 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset);
[email protected]17cfbe0e2013-03-07 01:26:086567 bool used_client_side_array = false;
6568 if (element_array_buffer->IsClientSideArray()) {
6569 used_client_side_array = true;
6570 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6571 indices = element_array_buffer->GetRange(offset, 0);
6572 }
6573
[email protected]c6aef902012-02-14 03:31:426574 if (!instanced) {
6575 glDrawElements(mode, count, type, indices);
6576 } else {
6577 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
6578 }
[email protected]17cfbe0e2013-03-07 01:26:086579
6580 if (used_client_side_array) {
6581 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
6582 element_array_buffer->service_id());
6583 }
6584
[email protected]22e3f552012-03-13 01:54:196585 ProcessPendingQueries();
[email protected]8fbedc02010-11-18 18:43:406586 if (textures_set) {
[email protected]91c94eb2013-10-22 10:32:546587 RestoreStateForTextures();
[email protected]8fbedc02010-11-18 18:43:406588 }
6589 if (simulated_fixed_attribs) {
6590 RestoreStateForSimulatedFixedAttribs();
6591 }
[email protected]ba3176a2009-12-16 18:19:466592 }
[email protected]b1122982010-05-17 23:04:246593 if (simulated_attrib_0) {
[email protected]43410e92012-04-20 17:06:286594 RestoreStateForAttrib(0);
[email protected]b1122982010-05-17 23:04:246595 }
[email protected]96449d2c2009-11-25 00:01:326596 }
[email protected]f7a64ee2010-02-01 22:24:146597 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326598}
6599
[email protected]c6aef902012-02-14 03:31:426600error::Error GLES2DecoderImpl::HandleDrawElements(
[email protected]ed9f9cd2013-02-27 21:12:356601 uint32 immediate_data_size, const cmds::DrawElements& c) {
[email protected]ad84a3a2012-06-08 21:42:436602 return DoDrawElements("glDrawElements",
6603 false,
[email protected]c6aef902012-02-14 03:31:426604 static_cast<GLenum>(c.mode),
6605 static_cast<GLsizei>(c.count),
6606 static_cast<GLenum>(c.type),
6607 static_cast<int32>(c.index_offset),
6608 0);
6609}
6610
6611error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
[email protected]ed9f9cd2013-02-27 21:12:356612 uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) {
[email protected]62e155e2012-10-23 22:43:156613 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:516614 LOCAL_SET_GL_ERROR(
6615 GL_INVALID_OPERATION,
6616 "glDrawElementsInstancedANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:426617 return error::kNoError;
6618 }
[email protected]ad84a3a2012-06-08 21:42:436619 return DoDrawElements("glDrawElementsInstancedANGLE",
6620 true,
[email protected]c6aef902012-02-14 03:31:426621 static_cast<GLenum>(c.mode),
6622 static_cast<GLsizei>(c.count),
6623 static_cast<GLenum>(c.type),
6624 static_cast<int32>(c.index_offset),
6625 static_cast<GLsizei>(c.primcount));
6626}
6627
[email protected]269200b12010-11-18 22:53:066628GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM(
[email protected]29a9eb52010-04-13 09:04:236629 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) {
6630 GLuint max_vertex_accessed = 0;
[email protected]b10492f2013-03-08 05:24:076631 Buffer* buffer = GetBuffer(buffer_id);
6632 if (!buffer) {
[email protected]ae51d192010-04-27 00:48:036633 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516634 LOCAL_SET_GL_ERROR(
6635 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer");
[email protected]29a9eb52010-04-13 09:04:236636 } else {
[email protected]b10492f2013-03-08 05:24:076637 if (!buffer->GetMaxValueForRange(
6638 offset, count, type, &max_vertex_accessed)) {
[email protected]ae51d192010-04-27 00:48:036639 // TODO(gman): Should this be a GL error or a command buffer error?
[email protected]ab09b612013-03-11 22:11:516640 LOCAL_SET_GL_ERROR(
[email protected]269200b12010-11-18 22:53:066641 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:436642 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer");
[email protected]29a9eb52010-04-13 09:04:236643 }
6644 }
6645 return max_vertex_accessed;
6646}
6647
[email protected]96449d2c2009-11-25 00:01:326648// Calls glShaderSource for the various versions of the ShaderSource command.
6649// Assumes that data / data_size points to a piece of memory that is in range
6650// of whatever context it came from (shared memory, immediate memory, bucket
6651// memory.)
[email protected]45bf5152010-02-12 00:11:316652error::Error GLES2DecoderImpl::ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036653 GLuint client_id, const char* data, uint32 data_size) {
[email protected]258a3313f2011-10-18 20:13:576654 std::string str(data, data + data_size);
[email protected]df37b9932013-03-08 05:21:426655 Shader* shader = GetShaderInfoNotProgram(client_id, "glShaderSource");
6656 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316657 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326658 }
[email protected]45bf5152010-02-12 00:11:316659 // Note: We don't actually call glShaderSource here. We wait until
6660 // the call to glCompileShader.
[email protected]df37b9932013-03-08 05:21:426661 shader->UpdateSource(str.c_str());
[email protected]f7a64ee2010-02-01 22:24:146662 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326663}
6664
[email protected]f7a64ee2010-02-01 22:24:146665error::Error GLES2DecoderImpl::HandleShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356666 uint32 immediate_data_size, const cmds::ShaderSource& c) {
[email protected]96449d2c2009-11-25 00:01:326667 uint32 data_size = c.data_size;
[email protected]45bf5152010-02-12 00:11:316668 const char* data = GetSharedMemoryAs<const char*>(
[email protected]96449d2c2009-11-25 00:01:326669 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]ba3176a2009-12-16 18:19:466670 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:146671 return error::kOutOfBounds;
[email protected]96449d2c2009-11-25 00:01:326672 }
[email protected]ae51d192010-04-27 00:48:036673 return ShaderSourceHelper(c.shader, data, data_size);
[email protected]96449d2c2009-11-25 00:01:326674}
6675
[email protected]558847a2010-03-24 07:02:546676error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
[email protected]ed9f9cd2013-02-27 21:12:356677 uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) {
[email protected]558847a2010-03-24 07:02:546678 Bucket* bucket = GetBucket(c.data_bucket_id);
6679 if (!bucket || bucket->size() == 0) {
6680 return error::kInvalidArguments;
6681 }
6682 return ShaderSourceHelper(
[email protected]ae51d192010-04-27 00:48:036683 c.shader, bucket->GetDataAs<const char*>(0, bucket->size() - 1),
[email protected]558847a2010-03-24 07:02:546684 bucket->size() - 1);
6685}
6686
[email protected]ae51d192010-04-27 00:48:036687void GLES2DecoderImpl::DoCompileShader(GLuint client_id) {
[email protected]43ed3a72012-05-30 22:55:386688 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompileShader");
[email protected]df37b9932013-03-08 05:21:426689 Shader* shader = GetShaderInfoNotProgram(client_id, "glCompileShader");
6690 if (!shader) {
[email protected]45bf5152010-02-12 00:11:316691 return;
6692 }
[email protected]f57bb282010-11-12 00:51:346693 ShaderTranslator* translator = NULL;
[email protected]b1d2dcb2010-05-17 19:24:186694 if (use_shader_translator_) {
[email protected]df37b9932013-03-08 05:21:426695 translator = shader->shader_type() == GL_VERTEX_SHADER ?
[email protected]a550584e2010-09-17 18:01:456696 vertex_translator_.get() : fragment_translator_.get();
[email protected]de17df392010-04-23 21:09:416697 }
[email protected]de17df392010-04-23 21:09:416698
[email protected]7cd76fd2013-06-02 21:11:116699 program_manager()->DoCompileShader(shader, translator, feature_info_.get());
[email protected]45bf5152010-02-12 00:11:316700};
6701
[email protected]ddd968b82010-03-02 00:44:296702void GLES2DecoderImpl::DoGetShaderiv(
[email protected]df37b9932013-03-08 05:21:426703 GLuint shader_id, GLenum pname, GLint* params) {
6704 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderiv");
6705 if (!shader) {
[email protected]ddd968b82010-03-02 00:44:296706 return;
6707 }
[email protected]8f1ccdac2010-05-19 21:01:486708 switch (pname) {
6709 case GL_SHADER_SOURCE_LENGTH:
[email protected]df37b9932013-03-08 05:21:426710 *params = shader->source() ? shader->source()->size() + 1 : 0;
[email protected]8f1ccdac2010-05-19 21:01:486711 return;
6712 case GL_COMPILE_STATUS:
[email protected]df37b9932013-03-08 05:21:426713 *params = compile_shader_always_succeeds_ ? true : shader->IsValid();
[email protected]e5186162010-06-14 18:54:416714 return;
[email protected]8f1ccdac2010-05-19 21:01:486715 case GL_INFO_LOG_LENGTH:
[email protected]df37b9932013-03-08 05:21:426716 *params = shader->log_info() ? shader->log_info()->size() + 1 : 0;
[email protected]e5186162010-06-14 18:54:416717 return;
[email protected]d6a53e42011-10-05 00:09:366718 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
[email protected]df37b9932013-03-08 05:21:426719 *params = shader->translated_source() ?
6720 shader->translated_source()->size() + 1 : 0;
[email protected]d6a53e42011-10-05 00:09:366721 return;
[email protected]8f1ccdac2010-05-19 21:01:486722 default:
6723 break;
[email protected]ddd968b82010-03-02 00:44:296724 }
[email protected]df37b9932013-03-08 05:21:426725 glGetShaderiv(shader->service_id(), pname, params);
[email protected]ddd968b82010-03-02 00:44:296726}
6727
[email protected]ae51d192010-04-27 00:48:036728error::Error GLES2DecoderImpl::HandleGetShaderSource(
[email protected]ed9f9cd2013-02-27 21:12:356729 uint32 immediate_data_size, const cmds::GetShaderSource& c) {
[email protected]df37b9932013-03-08 05:21:426730 GLuint shader_id = c.shader;
[email protected]ae51d192010-04-27 00:48:036731 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6732 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426733 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderSource");
6734 if (!shader || !shader->source()) {
[email protected]8eee29c2010-04-29 03:38:296735 bucket->SetSize(0);
[email protected]8eee29c2010-04-29 03:38:296736 return error::kNoError;
6737 }
[email protected]df37b9932013-03-08 05:21:426738 bucket->SetFromString(shader->source()->c_str());
[email protected]ae51d192010-04-27 00:48:036739 return error::kNoError;
6740}
6741
[email protected]d6a53e42011-10-05 00:09:366742error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
6743 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:356744 const cmds::GetTranslatedShaderSourceANGLE& c) {
[email protected]df37b9932013-03-08 05:21:426745 GLuint shader_id = c.shader;
[email protected]d6a53e42011-10-05 00:09:366746 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6747 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426748 Shader* shader = GetShaderInfoNotProgram(
6749 shader_id, "glTranslatedGetShaderSourceANGLE");
6750 if (!shader) {
[email protected]d6a53e42011-10-05 00:09:366751 bucket->SetSize(0);
6752 return error::kNoError;
6753 }
6754
[email protected]df37b9932013-03-08 05:21:426755 bucket->SetFromString(shader->translated_source() ?
6756 shader->translated_source()->c_str() : NULL);
[email protected]d6a53e42011-10-05 00:09:366757 return error::kNoError;
6758}
6759
[email protected]ae51d192010-04-27 00:48:036760error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356761 uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426762 GLuint program_id = c.program;
[email protected]6b8cf1a2010-05-06 16:13:586763 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6764 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426765 Program* program = GetProgramInfoNotShader(
6766 program_id, "glGetProgramInfoLog");
6767 if (!program || !program->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466768 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036769 return error::kNoError;
[email protected]45bf5152010-02-12 00:11:316770 }
[email protected]df37b9932013-03-08 05:21:426771 bucket->SetFromString(program->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036772 return error::kNoError;
6773}
6774
6775error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
[email protected]ed9f9cd2013-02-27 21:12:356776 uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) {
[email protected]df37b9932013-03-08 05:21:426777 GLuint shader_id = c.shader;
[email protected]6b8cf1a2010-05-06 16:13:586778 uint32 bucket_id = static_cast<uint32>(c.bucket_id);
6779 Bucket* bucket = CreateBucket(bucket_id);
[email protected]df37b9932013-03-08 05:21:426780 Shader* shader = GetShaderInfoNotProgram(shader_id, "glGetShaderInfoLog");
6781 if (!shader || !shader->log_info()) {
[email protected]9a14ae612011-08-08 17:51:466782 bucket->SetFromString("");
[email protected]ae51d192010-04-27 00:48:036783 return error::kNoError;
6784 }
[email protected]df37b9932013-03-08 05:21:426785 bucket->SetFromString(shader->log_info()->c_str());
[email protected]ae51d192010-04-27 00:48:036786 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:326787}
6788
[email protected]d058bca2012-11-26 10:27:266789bool GLES2DecoderImpl::DoIsEnabled(GLenum cap) {
6790 return state_.GetEnabled(cap);
6791}
6792
[email protected]1958e0e2010-04-22 05:17:156793bool GLES2DecoderImpl::DoIsBuffer(GLuint client_id) {
[email protected]16ccec12013-02-28 03:40:216794 const Buffer* buffer = GetBuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106795 return buffer && buffer->IsValid() && !buffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156796}
6797
6798bool GLES2DecoderImpl::DoIsFramebuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356799 const Framebuffer* framebuffer =
6800 GetFramebuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106801 return framebuffer && framebuffer->IsValid() && !framebuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156802}
6803
6804bool GLES2DecoderImpl::DoIsProgram(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366805 // IsProgram is true for programs as soon as they are created, until they are
6806 // deleted and no longer in use.
[email protected]ed9f9cd2013-02-27 21:12:356807 const Program* program = GetProgram(client_id);
[email protected]a0b78dc2011-11-11 10:43:106808 return program != NULL && !program->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156809}
6810
6811bool GLES2DecoderImpl::DoIsRenderbuffer(GLuint client_id) {
[email protected]ed9f9cd2013-02-27 21:12:356812 const Renderbuffer* renderbuffer =
6813 GetRenderbuffer(client_id);
[email protected]a0b78dc2011-11-11 10:43:106814 return renderbuffer && renderbuffer->IsValid() && !renderbuffer->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156815}
6816
6817bool GLES2DecoderImpl::DoIsShader(GLuint client_id) {
[email protected]06c8b082011-01-05 18:00:366818 // IsShader is true for shaders as soon as they are created, until they
6819 // are deleted and not attached to any programs.
[email protected]ed9f9cd2013-02-27 21:12:356820 const Shader* shader = GetShader(client_id);
[email protected]a0b78dc2011-11-11 10:43:106821 return shader != NULL && !shader->IsDeleted();
[email protected]1958e0e2010-04-22 05:17:156822}
6823
6824bool GLES2DecoderImpl::DoIsTexture(GLuint client_id) {
[email protected]370eaf12013-05-18 09:19:496825 const TextureRef* texture_ref = GetTexture(client_id);
6826 return texture_ref && texture_ref->texture()->IsValid();
[email protected]ae51d192010-04-27 00:48:036827}
6828
6829void GLES2DecoderImpl::DoAttachShader(
6830 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426831 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586832 program_client_id, "glAttachShader");
[email protected]df37b9932013-03-08 05:21:426833 if (!program) {
[email protected]ae51d192010-04-27 00:48:036834 return;
[email protected]1958e0e2010-04-22 05:17:156835 }
[email protected]df37b9932013-03-08 05:21:426836 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glAttachShader");
6837 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036838 return;
6839 }
[email protected]df37b9932013-03-08 05:21:426840 if (!program->AttachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516841 LOCAL_SET_GL_ERROR(
6842 GL_INVALID_OPERATION,
6843 "glAttachShader",
6844 "can not attach more than one shader of the same type.");
[email protected]fb96c8e2010-08-12 04:10:316845 return;
6846 }
[email protected]df37b9932013-03-08 05:21:426847 glAttachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036848}
6849
6850void GLES2DecoderImpl::DoDetachShader(
6851 GLuint program_client_id, GLint shader_client_id) {
[email protected]df37b9932013-03-08 05:21:426852 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586853 program_client_id, "glDetachShader");
[email protected]df37b9932013-03-08 05:21:426854 if (!program) {
[email protected]ae51d192010-04-27 00:48:036855 return;
6856 }
[email protected]df37b9932013-03-08 05:21:426857 Shader* shader = GetShaderInfoNotProgram(shader_client_id, "glDetachShader");
6858 if (!shader) {
[email protected]ae51d192010-04-27 00:48:036859 return;
6860 }
[email protected]df37b9932013-03-08 05:21:426861 if (!program->DetachShader(shader_manager(), shader)) {
[email protected]ab09b612013-03-11 22:11:516862 LOCAL_SET_GL_ERROR(
6863 GL_INVALID_OPERATION,
6864 "glDetachShader", "shader not attached to program");
[email protected]9a0ccd42011-03-16 23:58:226865 return;
6866 }
[email protected]df37b9932013-03-08 05:21:426867 glDetachShader(program->service_id(), shader->service_id());
[email protected]ae51d192010-04-27 00:48:036868}
6869
6870void GLES2DecoderImpl::DoValidateProgram(GLuint program_client_id) {
[email protected]df37b9932013-03-08 05:21:426871 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:586872 program_client_id, "glValidateProgram");
[email protected]df37b9932013-03-08 05:21:426873 if (!program) {
[email protected]ae51d192010-04-27 00:48:036874 return;
6875 }
[email protected]df37b9932013-03-08 05:21:426876 program->Validate();
[email protected]1958e0e2010-04-22 05:17:156877}
6878
[email protected]ac77603c72013-03-08 13:52:066879void GLES2DecoderImpl::GetVertexAttribHelper(
6880 const VertexAttrib* attrib, GLenum pname, GLint* params) {
[email protected]b1122982010-05-17 23:04:246881 switch (pname) {
6882 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
[email protected]ac77603c72013-03-08 13:52:066883 Buffer* buffer = attrib->buffer();
[email protected]b1122982010-05-17 23:04:246884 if (buffer && !buffer->IsDeleted()) {
6885 GLuint client_id;
6886 buffer_manager()->GetClientId(buffer->service_id(), &client_id);
6887 *params = client_id;
6888 }
6889 break;
6890 }
6891 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
[email protected]ac77603c72013-03-08 13:52:066892 *params = attrib->enabled();
[email protected]b1122982010-05-17 23:04:246893 break;
6894 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
[email protected]ac77603c72013-03-08 13:52:066895 *params = attrib->size();
[email protected]b1122982010-05-17 23:04:246896 break;
6897 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
[email protected]ac77603c72013-03-08 13:52:066898 *params = attrib->gl_stride();
[email protected]b1122982010-05-17 23:04:246899 break;
6900 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
[email protected]ac77603c72013-03-08 13:52:066901 *params = attrib->type();
[email protected]b1122982010-05-17 23:04:246902 break;
6903 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
[email protected]ac77603c72013-03-08 13:52:066904 *params = attrib->normalized();
[email protected]b1122982010-05-17 23:04:246905 break;
[email protected]c6aef902012-02-14 03:31:426906 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
[email protected]ac77603c72013-03-08 13:52:066907 *params = attrib->divisor();
[email protected]c6aef902012-02-14 03:31:426908 break;
[email protected]ac77603c72013-03-08 13:52:066909 default:
6910 NOTREACHED();
6911 break;
6912 }
6913}
6914
6915void GLES2DecoderImpl::DoGetVertexAttribfv(
6916 GLuint index, GLenum pname, GLfloat* params) {
6917 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6918 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516919 LOCAL_SET_GL_ERROR(
6920 GL_INVALID_VALUE, "glGetVertexAttribfv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066921 return;
6922 }
6923 switch (pname) {
6924 case GL_CURRENT_VERTEX_ATTRIB: {
6925 const Vec4& value = state_.attrib_values[index];
6926 params[0] = value.v[0];
6927 params[1] = value.v[1];
6928 params[2] = value.v[2];
6929 params[3] = value.v[3];
6930 break;
6931 }
6932 default: {
6933 GLint value = 0;
6934 GetVertexAttribHelper(attrib, pname, &value);
6935 *params = static_cast<GLfloat>(value);
6936 break;
6937 }
6938 }
6939}
6940
6941void GLES2DecoderImpl::DoGetVertexAttribiv(
6942 GLuint index, GLenum pname, GLint* params) {
6943 VertexAttrib* attrib = state_.vertex_attrib_manager->GetVertexAttrib(index);
6944 if (!attrib) {
[email protected]ab09b612013-03-11 22:11:516945 LOCAL_SET_GL_ERROR(
6946 GL_INVALID_VALUE, "glGetVertexAttribiv", "index out of range");
[email protected]ac77603c72013-03-08 13:52:066947 return;
6948 }
6949 switch (pname) {
[email protected]af6380962012-11-29 23:24:136950 case GL_CURRENT_VERTEX_ATTRIB: {
6951 const Vec4& value = state_.attrib_values[index];
6952 params[0] = static_cast<GLint>(value.v[0]);
6953 params[1] = static_cast<GLint>(value.v[1]);
6954 params[2] = static_cast<GLint>(value.v[2]);
6955 params[3] = static_cast<GLint>(value.v[3]);
[email protected]b1122982010-05-17 23:04:246956 break;
[email protected]af6380962012-11-29 23:24:136957 }
[email protected]b1122982010-05-17 23:04:246958 default:
[email protected]ac77603c72013-03-08 13:52:066959 GetVertexAttribHelper(attrib, pname, params);
[email protected]b1122982010-05-17 23:04:246960 break;
6961 }
6962}
6963
[email protected]af6380962012-11-29 23:24:136964bool GLES2DecoderImpl::SetVertexAttribValue(
6965 const char* function_name, GLuint index, const GLfloat* value) {
6966 if (index >= state_.attrib_values.size()) {
[email protected]ab09b612013-03-11 22:11:516967 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "index out of range");
[email protected]af6380962012-11-29 23:24:136968 return false;
[email protected]b1122982010-05-17 23:04:246969 }
[email protected]af6380962012-11-29 23:24:136970 Vec4& v = state_.attrib_values[index];
6971 v.v[0] = value[0];
6972 v.v[1] = value[1];
6973 v.v[2] = value[2];
6974 v.v[3] = value[3];
6975 return true;
6976}
6977
6978void GLES2DecoderImpl::DoVertexAttrib1f(GLuint index, GLfloat v0) {
6979 GLfloat v[4] = { v0, 0.0f, 0.0f, 1.0f, };
6980 if (SetVertexAttribValue("glVertexAttrib1f", index, v)) {
6981 glVertexAttrib1f(index, v0);
6982 }
[email protected]b1122982010-05-17 23:04:246983}
6984
6985void GLES2DecoderImpl::DoVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) {
[email protected]af6380962012-11-29 23:24:136986 GLfloat v[4] = { v0, v1, 0.0f, 1.0f, };
6987 if (SetVertexAttribValue("glVertexAttrib2f", index, v)) {
6988 glVertexAttrib2f(index, v0, v1);
[email protected]b1122982010-05-17 23:04:246989 }
[email protected]b1122982010-05-17 23:04:246990}
6991
6992void GLES2DecoderImpl::DoVertexAttrib3f(
6993 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) {
[email protected]af6380962012-11-29 23:24:136994 GLfloat v[4] = { v0, v1, v2, 1.0f, };
6995 if (SetVertexAttribValue("glVertexAttrib3f", index, v)) {
6996 glVertexAttrib3f(index, v0, v1, v2);
[email protected]b1122982010-05-17 23:04:246997 }
[email protected]b1122982010-05-17 23:04:246998}
6999
7000void GLES2DecoderImpl::DoVertexAttrib4f(
7001 GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {
[email protected]af6380962012-11-29 23:24:137002 GLfloat v[4] = { v0, v1, v2, v3, };
7003 if (SetVertexAttribValue("glVertexAttrib4f", index, v)) {
7004 glVertexAttrib4f(index, v0, v1, v2, v3);
[email protected]b1122982010-05-17 23:04:247005 }
[email protected]b1122982010-05-17 23:04:247006}
7007
7008void GLES2DecoderImpl::DoVertexAttrib1fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137009 GLfloat t[4] = { v[0], 0.0f, 0.0f, 1.0f, };
7010 if (SetVertexAttribValue("glVertexAttrib1fv", index, t)) {
7011 glVertexAttrib1fv(index, v);
[email protected]b1122982010-05-17 23:04:247012 }
[email protected]b1122982010-05-17 23:04:247013}
7014
7015void GLES2DecoderImpl::DoVertexAttrib2fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137016 GLfloat t[4] = { v[0], v[1], 0.0f, 1.0f, };
7017 if (SetVertexAttribValue("glVertexAttrib2fv", index, t)) {
7018 glVertexAttrib2fv(index, v);
[email protected]b1122982010-05-17 23:04:247019 }
[email protected]b1122982010-05-17 23:04:247020}
7021
7022void GLES2DecoderImpl::DoVertexAttrib3fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137023 GLfloat t[4] = { v[0], v[1], v[2], 1.0f, };
7024 if (SetVertexAttribValue("glVertexAttrib3fv", index, t)) {
7025 glVertexAttrib3fv(index, v);
[email protected]b1122982010-05-17 23:04:247026 }
[email protected]b1122982010-05-17 23:04:247027}
7028
7029void GLES2DecoderImpl::DoVertexAttrib4fv(GLuint index, const GLfloat* v) {
[email protected]af6380962012-11-29 23:24:137030 if (SetVertexAttribValue("glVertexAttrib4fv", index, v)) {
7031 glVertexAttrib4fv(index, v);
[email protected]b1122982010-05-17 23:04:247032 }
[email protected]b1122982010-05-17 23:04:247033}
7034
[email protected]f7a64ee2010-02-01 22:24:147035error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
[email protected]ed9f9cd2013-02-27 21:12:357036 uint32 immediate_data_size, const cmds::VertexAttribPointer& c) {
[email protected]944b62f32012-09-27 02:20:467037
[email protected]7cd76fd2013-06-02 21:11:117038 if (!state_.bound_array_buffer.get() ||
7039 state_.bound_array_buffer->IsDeleted()) {
7040 if (state_.vertex_attrib_manager.get() ==
7041 default_vertex_attrib_manager_.get()) {
[email protected]ab09b612013-03-11 22:11:517042 LOCAL_SET_GL_ERROR(
7043 GL_INVALID_VALUE, "glVertexAttribPointer", "no array buffer bound");
[email protected]944b62f32012-09-27 02:20:467044 return error::kNoError;
7045 } else if (c.offset != 0) {
[email protected]ab09b612013-03-11 22:11:517046 LOCAL_SET_GL_ERROR(
7047 GL_INVALID_VALUE,
7048 "glVertexAttribPointer", "client side arrays are not allowed");
[email protected]944b62f32012-09-27 02:20:467049 return error::kNoError;
7050 }
[email protected]96449d2c2009-11-25 00:01:327051 }
[email protected]8eee29c2010-04-29 03:38:297052
7053 GLuint indx = c.indx;
7054 GLint size = c.size;
7055 GLenum type = c.type;
7056 GLboolean normalized = c.normalized;
7057 GLsizei stride = c.stride;
7058 GLsizei offset = c.offset;
7059 const void* ptr = reinterpret_cast<const void*>(offset);
[email protected]9438b012010-06-15 22:55:057060 if (!validators_->vertex_attrib_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517061 LOCAL_SET_GL_ERROR_INVALID_ENUM("glVertexAttribPointer", type, "type");
[email protected]8eee29c2010-04-29 03:38:297062 return error::kNoError;
7063 }
[email protected]9438b012010-06-15 22:55:057064 if (!validators_->vertex_attrib_size.IsValid(size)) {
[email protected]ab09b612013-03-11 22:11:517065 LOCAL_SET_GL_ERROR(
7066 GL_INVALID_VALUE, "glVertexAttribPointer", "size GL_INVALID_VALUE");
[email protected]8eee29c2010-04-29 03:38:297067 return error::kNoError;
7068 }
7069 if (indx >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517070 LOCAL_SET_GL_ERROR(
7071 GL_INVALID_VALUE, "glVertexAttribPointer", "index out of range");
[email protected]8eee29c2010-04-29 03:38:297072 return error::kNoError;
7073 }
7074 if (stride < 0) {
[email protected]ab09b612013-03-11 22:11:517075 LOCAL_SET_GL_ERROR(
7076 GL_INVALID_VALUE, "glVertexAttribPointer", "stride < 0");
[email protected]8eee29c2010-04-29 03:38:297077 return error::kNoError;
7078 }
7079 if (stride > 255) {
[email protected]ab09b612013-03-11 22:11:517080 LOCAL_SET_GL_ERROR(
7081 GL_INVALID_VALUE, "glVertexAttribPointer", "stride > 255");
[email protected]8eee29c2010-04-29 03:38:297082 return error::kNoError;
7083 }
7084 if (offset < 0) {
[email protected]ab09b612013-03-11 22:11:517085 LOCAL_SET_GL_ERROR(
7086 GL_INVALID_VALUE, "glVertexAttribPointer", "offset < 0");
[email protected]8eee29c2010-04-29 03:38:297087 return error::kNoError;
7088 }
7089 GLsizei component_size =
[email protected]ff81c192011-01-07 23:04:317090 GLES2Util::GetGLTypeSizeForTexturesAndBuffers(type);
[email protected]8eee29c2010-04-29 03:38:297091 if (offset % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:517092 LOCAL_SET_GL_ERROR(
7093 GL_INVALID_OPERATION,
7094 "glVertexAttribPointer", "offset not valid for type");
[email protected]ff81c192011-01-07 23:04:317095 return error::kNoError;
7096 }
7097 if (stride % component_size > 0) {
[email protected]ab09b612013-03-11 22:11:517098 LOCAL_SET_GL_ERROR(
7099 GL_INVALID_OPERATION,
7100 "glVertexAttribPointer", "stride not valid for type");
[email protected]8eee29c2010-04-29 03:38:297101 return error::kNoError;
7102 }
[email protected]7cd76fd2013-06-02 21:11:117103 state_.vertex_attrib_manager
7104 ->SetAttribInfo(indx,
7105 state_.bound_array_buffer.get(),
7106 size,
7107 type,
7108 normalized,
7109 stride,
7110 stride != 0 ? stride : component_size * size,
7111 offset);
[email protected]8fbedc02010-11-18 18:43:407112 if (type != GL_FIXED) {
7113 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
7114 }
[email protected]f7a64ee2010-02-01 22:24:147115 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327116}
7117
[email protected]43410e92012-04-20 17:06:287118void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width,
7119 GLsizei height) {
[email protected]e259eb412012-10-13 05:47:247120 state_.viewport_x = x;
7121 state_.viewport_y = y;
[email protected]1868a342012-11-07 15:56:027122 state_.viewport_width = std::min(width, viewport_max_width_);
7123 state_.viewport_height = std::min(height, viewport_max_height_);
[email protected]43410e92012-04-20 17:06:287124 glViewport(x, y, width, height);
7125}
7126
[email protected]c6aef902012-02-14 03:31:427127error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
[email protected]ed9f9cd2013-02-27 21:12:357128 uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) {
[email protected]62e155e2012-10-23 22:43:157129 if (!features().angle_instanced_arrays) {
[email protected]ab09b612013-03-11 22:11:517130 LOCAL_SET_GL_ERROR(
7131 GL_INVALID_OPERATION,
7132 "glVertexAttribDivisorANGLE", "function not available");
[email protected]c6aef902012-02-14 03:31:427133 }
7134 GLuint index = c.index;
7135 GLuint divisor = c.divisor;
7136 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:517137 LOCAL_SET_GL_ERROR(
7138 GL_INVALID_VALUE,
7139 "glVertexAttribDivisorANGLE", "index out of range");
[email protected]c6aef902012-02-14 03:31:427140 return error::kNoError;
7141 }
7142
[email protected]e259eb412012-10-13 05:47:247143 state_.vertex_attrib_manager->SetDivisor(
[email protected]c6aef902012-02-14 03:31:427144 index,
7145 divisor);
7146 glVertexAttribDivisorANGLE(index, divisor);
7147 return error::kNoError;
7148}
7149
[email protected]68586372013-12-11 01:27:597150template <typename pixel_data_type>
7151static void WriteAlphaData(
7152 void *pixels, uint32 row_count, uint32 channel_count,
7153 uint32 alpha_channel_index, uint32 unpadded_row_size,
7154 uint32 padded_row_size, pixel_data_type alpha_value) {
7155 DCHECK_GT(channel_count, 0U);
7156 DCHECK_EQ(unpadded_row_size % sizeof(pixel_data_type), 0U);
7157 uint32 unpadded_row_size_in_elements =
7158 unpadded_row_size / sizeof(pixel_data_type);
7159 DCHECK_EQ(padded_row_size % sizeof(pixel_data_type), 0U);
7160 uint32 padded_row_size_in_elements =
7161 padded_row_size / sizeof(pixel_data_type);
7162 pixel_data_type* dst =
7163 static_cast<pixel_data_type*>(pixels) + alpha_channel_index;
7164 for (uint32 yy = 0; yy < row_count; ++yy) {
7165 pixel_data_type* end = dst + unpadded_row_size_in_elements;
7166 for (pixel_data_type* d = dst; d < end; d += channel_count) {
7167 *d = alpha_value;
7168 }
7169 dst += padded_row_size_in_elements;
7170 }
7171}
7172
[email protected]5a36dc132013-07-23 23:17:557173void GLES2DecoderImpl::FinishReadPixels(
7174 const cmds::ReadPixels& c,
7175 GLuint buffer) {
7176 TRACE_EVENT0("gpu", "GLES2DecoderImpl::FinishReadPixels");
7177 GLsizei width = c.width;
7178 GLsizei height = c.height;
7179 GLenum format = c.format;
7180 GLenum type = c.type;
7181 typedef cmds::ReadPixels::Result Result;
7182 uint32 pixels_size;
7183 Result* result = NULL;
7184 if (c.result_shm_id != 0) {
7185 result = GetSharedMemoryAs<Result*>(
7186 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7187 if (!result) {
7188 if (buffer != 0) {
7189 glDeleteBuffersARB(1, &buffer);
7190 }
7191 return;
7192 }
7193 }
7194 GLES2Util::ComputeImageDataSizes(
7195 width, height, format, type, state_.pack_alignment, &pixels_size,
7196 NULL, NULL);
7197 void* pixels = GetSharedMemoryAs<void*>(
7198 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
7199 if (!pixels) {
7200 if (buffer != 0) {
7201 glDeleteBuffersARB(1, &buffer);
7202 }
7203 return;
7204 }
7205
7206 if (buffer != 0) {
7207 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
[email protected]e585f9e22013-08-27 02:50:337208 void* data;
7209 if (features().map_buffer_range) {
7210 data = glMapBufferRange(
7211 GL_PIXEL_PACK_BUFFER_ARB, 0, pixels_size, GL_MAP_READ_BIT);
7212 } else {
7213 data = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
7214 }
[email protected]5a36dc132013-07-23 23:17:557215 memcpy(pixels, data, pixels_size);
7216 // GL_PIXEL_PACK_BUFFER_ARB is currently unused, so we don't
7217 // have to restore the state.
7218 glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
7219 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7220 glDeleteBuffersARB(1, &buffer);
7221 }
7222
7223 if (result != NULL) {
7224 *result = true;
7225 }
7226
7227 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
7228 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
7229 if ((channels_exist & 0x0008) == 0 &&
7230 workarounds().clear_alpha_in_readpixels) {
7231 // Set the alpha to 255 because some drivers are buggy in this regard.
7232 uint32 temp_size;
7233
7234 uint32 unpadded_row_size;
7235 uint32 padded_row_size;
7236 if (!GLES2Util::ComputeImageDataSizes(
7237 width, 2, format, type, state_.pack_alignment, &temp_size,
7238 &unpadded_row_size, &padded_row_size)) {
7239 return;
7240 }
[email protected]68586372013-12-11 01:27:597241
7242 uint32 channel_count = 0;
7243 uint32 alpha_channel = 0;
[email protected]5a36dc132013-07-23 23:17:557244 switch (format) {
7245 case GL_RGBA:
7246 case GL_BGRA_EXT:
[email protected]68586372013-12-11 01:27:597247 channel_count = 4;
7248 alpha_channel = 3;
[email protected]5a36dc132013-07-23 23:17:557249 break;
[email protected]68586372013-12-11 01:27:597250 case GL_ALPHA:
7251 channel_count = 1;
7252 alpha_channel = 0;
7253 break;
7254 }
7255
7256 if (channel_count > 0) {
7257 switch (type) {
7258 case GL_UNSIGNED_BYTE:
7259 WriteAlphaData<uint8>(
7260 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7261 padded_row_size, 0xFF);
7262 break;
7263 case GL_FLOAT:
7264 WriteAlphaData<float>(
7265 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7266 padded_row_size, 1.0f);
7267 break;
7268 case GL_HALF_FLOAT:
7269 WriteAlphaData<uint16>(
7270 pixels, height, channel_count, alpha_channel, unpadded_row_size,
7271 padded_row_size, 0x3C00);
7272 break;
[email protected]5a36dc132013-07-23 23:17:557273 }
[email protected]5a36dc132013-07-23 23:17:557274 }
7275 }
7276}
7277
7278
[email protected]f7a64ee2010-02-01 22:24:147279error::Error GLES2DecoderImpl::HandleReadPixels(
[email protected]ed9f9cd2013-02-27 21:12:357280 uint32 immediate_data_size, const cmds::ReadPixels& c) {
[email protected]c76fe672013-12-13 23:30:227281 error::Error fbo_error = WillAccessBoundFramebufferForRead();
7282 if (fbo_error != error::kNoError)
7283 return fbo_error;
[email protected]612d2f82009-12-08 20:49:317284 GLint x = c.x;
7285 GLint y = c.y;
7286 GLsizei width = c.width;
7287 GLsizei height = c.height;
7288 GLenum format = c.format;
7289 GLenum type = c.type;
[email protected]5a36dc132013-07-23 23:17:557290 GLboolean async = c.async;
[email protected]57f223832010-03-19 01:57:567291 if (width < 0 || height < 0) {
[email protected]ab09b612013-03-11 22:11:517292 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glReadPixels", "dimensions < 0");
[email protected]57f223832010-03-19 01:57:567293 return error::kNoError;
7294 }
[email protected]ed9f9cd2013-02-27 21:12:357295 typedef cmds::ReadPixels::Result Result;
[email protected]a76b0052010-03-05 00:33:187296 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:347297 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247298 width, height, format, type, state_.pack_alignment, &pixels_size,
7299 NULL, NULL)) {
[email protected]a76b0052010-03-05 00:33:187300 return error::kOutOfBounds;
7301 }
[email protected]612d2f82009-12-08 20:49:317302 void* pixels = GetSharedMemoryAs<void*>(
7303 c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
[email protected]de43f082013-04-02 01:16:107304 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:147305 return error::kOutOfBounds;
[email protected]ba3176a2009-12-16 18:19:467306 }
[email protected]de43f082013-04-02 01:16:107307 Result* result = NULL;
7308 if (c.result_shm_id != 0) {
7309 result = GetSharedMemoryAs<Result*>(
7310 c.result_shm_id, c.result_shm_offset, sizeof(*result));
7311 if (!result) {
7312 return error::kOutOfBounds;
7313 }
7314 }
[email protected]a51788e2010-02-24 21:54:257315
[email protected]9438b012010-06-15 22:55:057316 if (!validators_->read_pixel_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:517317 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", format, "format");
[email protected]8eee29c2010-04-29 03:38:297318 return error::kNoError;
7319 }
[email protected]68586372013-12-11 01:27:597320 if (!validators_->read_pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:517321 LOCAL_SET_GL_ERROR_INVALID_ENUM("glReadPixels", type, "type");
[email protected]d2cf0a2d2010-02-25 21:36:127322 return error::kNoError;
7323 }
[email protected]68586372013-12-11 01:27:597324 if ((format != GL_RGBA && format != GL_BGRA_EXT && format != GL_RGB &&
7325 format != GL_ALPHA) || type != GL_UNSIGNED_BYTE) {
7326 // format and type are acceptable enums but not guaranteed to be supported
7327 // for this framebuffer. Have to ask gl if they are valid.
7328 GLint preferred_format = 0;
7329 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &preferred_format);
7330 GLint preferred_type = 0;
7331 DoGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &preferred_type);
7332 if (format != static_cast<GLenum>(preferred_format) ||
7333 type != static_cast<GLenum>(preferred_type)) {
7334 LOCAL_SET_GL_ERROR(
7335 GL_INVALID_OPERATION, "glReadPixels", "format and type incompatible "
7336 "with the current read framebuffer");
7337 return error::kNoError;
7338 }
7339 }
[email protected]57f223832010-03-19 01:57:567340 if (width == 0 || height == 0) {
7341 return error::kNoError;
7342 }
7343
[email protected]57f223832010-03-19 01:57:567344 // Get the size of the current fbo or backbuffer.
[email protected]8e3e0662010-08-23 18:46:307345 gfx::Size max_size = GetBoundReadFrameBufferSize();
[email protected]57f223832010-03-19 01:57:567346
[email protected]3aad1a32012-09-07 20:54:477347 int32 max_x;
7348 int32 max_y;
7349 if (!SafeAddInt32(x, width, &max_x) || !SafeAddInt32(y, height, &max_y)) {
[email protected]ab09b612013-03-11 22:11:517350 LOCAL_SET_GL_ERROR(
7351 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]f7a64ee2010-02-01 22:24:147352 return error::kNoError;
[email protected]612d2f82009-12-08 20:49:317353 }
[email protected]57f223832010-03-19 01:57:567354
[email protected]0d6bfdc2011-11-02 01:32:207355 if (!CheckBoundFramebuffersValid("glReadPixels")) {
7356 return error::kNoError;
7357 }
7358
[email protected]ab09b612013-03-11 22:11:517359 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glReadPixel");
[email protected]a0b78dc2011-11-11 10:43:107360
7361 ScopedResolvedFrameBufferBinder binder(this, false, true);
7362
[email protected]d37231fa2010-04-09 21:16:027363 if (x < 0 || y < 0 || max_x > max_size.width() || max_y > max_size.height()) {
[email protected]57f223832010-03-19 01:57:567364 // The user requested an out of range area. Get the results 1 line
7365 // at a time.
7366 uint32 temp_size;
[email protected]3458a64a2012-04-10 17:39:347367 uint32 unpadded_row_size;
7368 uint32 padded_row_size;
7369 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247370 width, 2, format, type, state_.pack_alignment, &temp_size,
[email protected]3458a64a2012-04-10 17:39:347371 &unpadded_row_size, &padded_row_size)) {
[email protected]ab09b612013-03-11 22:11:517372 LOCAL_SET_GL_ERROR(
7373 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567374 return error::kNoError;
7375 }
7376
7377 GLint dest_x_offset = std::max(-x, 0);
7378 uint32 dest_row_offset;
[email protected]3458a64a2012-04-10 17:39:347379 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247380 dest_x_offset, 1, format, type, state_.pack_alignment, &dest_row_offset,
7381 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:517382 LOCAL_SET_GL_ERROR(
7383 GL_INVALID_VALUE, "glReadPixels", "dimensions out of range");
[email protected]57f223832010-03-19 01:57:567384 return error::kNoError;
7385 }
7386
7387 // Copy each row into the larger dest rect.
7388 int8* dst = static_cast<int8*>(pixels);
7389 GLint read_x = std::max(0, x);
[email protected]d37231fa2010-04-09 21:16:027390 GLint read_end_x = std::max(0, std::min(max_size.width(), max_x));
[email protected]57f223832010-03-19 01:57:567391 GLint read_width = read_end_x - read_x;
7392 for (GLint yy = 0; yy < height; ++yy) {
7393 GLint ry = y + yy;
7394
7395 // Clear the row.
7396 memset(dst, 0, unpadded_row_size);
7397
7398 // If the row is in range, copy it.
[email protected]d37231fa2010-04-09 21:16:027399 if (ry >= 0 && ry < max_size.height() && read_width > 0) {
[email protected]57f223832010-03-19 01:57:567400 glReadPixels(
7401 read_x, ry, read_width, 1, format, type, dst + dest_row_offset);
7402 }
7403 dst += padded_row_size;
7404 }
7405 } else {
[email protected]5a36dc132013-07-23 23:17:557406 if (async && features().use_async_readpixels) {
7407 GLuint buffer;
7408 glGenBuffersARB(1, &buffer);
7409 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer);
7410 glBufferData(GL_PIXEL_PACK_BUFFER_ARB, pixels_size, NULL, GL_STREAM_READ);
7411 GLenum error = glGetError();
7412 if (error == GL_NO_ERROR) {
7413 glReadPixels(x, y, width, height, format, type, 0);
7414 pending_readpixel_fences_.push(linked_ptr<FenceCallback>(
7415 new FenceCallback()));
7416 WaitForReadPixels(base::Bind(
7417 &GLES2DecoderImpl::FinishReadPixels,
7418 base::internal::SupportsWeakPtrBase::StaticAsWeakPtr
7419 <GLES2DecoderImpl>(this),
7420 c, buffer));
7421 glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
7422 return error::kNoError;
7423 }
7424 }
[email protected]57f223832010-03-19 01:57:567425 glReadPixels(x, y, width, height, format, type, pixels);
7426 }
[email protected]ab09b612013-03-11 22:11:517427 GLenum error = LOCAL_PEEK_GL_ERROR("glReadPixels");
[email protected]a51788e2010-02-24 21:54:257428 if (error == GL_NO_ERROR) {
[email protected]de43f082013-04-02 01:16:107429 if (result != NULL) {
7430 *result = true;
7431 }
[email protected]5a36dc132013-07-23 23:17:557432 FinishReadPixels(c, 0);
[email protected]a51788e2010-02-24 21:54:257433 }
[email protected]4848b9f82011-03-10 18:37:567434
[email protected]f7a64ee2010-02-01 22:24:147435 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:327436}
7437
[email protected]f7a64ee2010-02-01 22:24:147438error::Error GLES2DecoderImpl::HandlePixelStorei(
[email protected]ed9f9cd2013-02-27 21:12:357439 uint32 immediate_data_size, const cmds::PixelStorei& c) {
[email protected]b9849abf2009-11-25 19:13:197440 GLenum pname = c.pname;
7441 GLenum param = c.param;
[email protected]9438b012010-06-15 22:55:057442 if (!validators_->pixel_store.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:517443 LOCAL_SET_GL_ERROR_INVALID_ENUM("glPixelStorei", pname, "pname");
[email protected]d2cf0a2d2010-02-25 21:36:127444 return error::kNoError;
7445 }
[email protected]222471d2011-11-30 18:06:397446 switch (pname) {
7447 case GL_PACK_ALIGNMENT:
7448 case GL_UNPACK_ALIGNMENT:
7449 if (!validators_->pixel_store_alignment.IsValid(param)) {
[email protected]ab09b612013-03-11 22:11:517450 LOCAL_SET_GL_ERROR(
7451 GL_INVALID_VALUE, "glPixelStore", "param GL_INVALID_VALUE");
[email protected]222471d2011-11-30 18:06:397452 return error::kNoError;
7453 }
[email protected]164d6d52012-05-05 00:55:037454 break;
[email protected]0a1e9ad2012-05-04 21:13:037455 case GL_UNPACK_FLIP_Y_CHROMIUM:
7456 unpack_flip_y_ = (param != 0);
7457 return error::kNoError;
7458 case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM:
7459 unpack_premultiply_alpha_ = (param != 0);
7460 return error::kNoError;
[email protected]6c75c712012-06-19 15:43:177461 case GL_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM:
7462 unpack_unpremultiply_alpha_ = (param != 0);
7463 return error::kNoError;
[email protected]222471d2011-11-30 18:06:397464 default:
7465 break;
[email protected]b9849abf2009-11-25 19:13:197466 }
7467 glPixelStorei(pname, param);
7468 switch (pname) {
[email protected]ad84a3a2012-06-08 21:42:437469 case GL_PACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247470 state_.pack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437471 break;
7472 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
[email protected]88a61bf2012-10-27 13:00:427473 state_.pack_reverse_row_order = (param != 0);
[email protected]ad84a3a2012-06-08 21:42:437474 break;
7475 case GL_UNPACK_ALIGNMENT:
[email protected]e259eb412012-10-13 05:47:247476 state_.unpack_alignment = param;
[email protected]ad84a3a2012-06-08 21:42:437477 break;
7478 default:
7479 // Validation should have prevented us from getting here.
7480 NOTREACHED();
7481 break;
[email protected]b9849abf2009-11-25 19:13:197482 }
[email protected]f7a64ee2010-02-01 22:24:147483 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197484}
7485
[email protected]1c75a3702011-11-11 14:15:287486error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:357487 uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) {
[email protected]43ed3a72012-05-30 22:55:387488 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
[email protected]6f5fac9d12012-06-26 21:02:457489 if (!surface_->HasExtension("GL_CHROMIUM_post_sub_buffer")) {
[email protected]ab09b612013-03-11 22:11:517490 LOCAL_SET_GL_ERROR(
7491 GL_INVALID_OPERATION,
7492 "glPostSubBufferCHROMIUM", "command not supported by surface");
[email protected]1c75a3702011-11-11 14:15:287493 return error::kNoError;
7494 }
[email protected]8f9b8dd2013-09-12 18:05:137495 bool is_tracing;
7496 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
7497 &is_tracing);
7498 if (is_tracing) {
7499 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
7500 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
7501 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
7502 is_offscreen ? offscreen_size_ : surface_->GetSize());
7503 }
[email protected]7794d512012-04-17 20:36:497504 if (surface_->PostSubBuffer(c.x, c.y, c.width, c.height)) {
[email protected]1c75a3702011-11-11 14:15:287505 return error::kNoError;
[email protected]7794d512012-04-17 20:36:497506 } else {
7507 LOG(ERROR) << "Context lost because PostSubBuffer failed.";
[email protected]1c75a3702011-11-11 14:15:287508 return error::kLostContext;
[email protected]7794d512012-04-17 20:36:497509 }
[email protected]1c75a3702011-11-11 14:15:287510}
7511
[email protected]558847a2010-03-24 07:02:547512error::Error GLES2DecoderImpl::GetAttribLocationHelper(
7513 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7514 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577515 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517516 LOCAL_SET_GL_ERROR(
7517 GL_INVALID_VALUE, "glGetAttribLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577518 return error::kNoError;
7519 }
[email protected]df37b9932013-03-08 05:21:427520 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587521 client_id, "glGetAttribLocation");
[email protected]df37b9932013-03-08 05:21:427522 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147523 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197524 }
[email protected]df37b9932013-03-08 05:21:427525 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517526 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437527 GL_INVALID_OPERATION, "glGetAttribLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257528 return error::kNoError;
7529 }
[email protected]b9849abf2009-11-25 19:13:197530 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547531 location_shm_id, location_shm_offset, sizeof(GLint));
7532 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147533 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197534 }
[email protected]558847a2010-03-24 07:02:547535 // Require the client to init this incase the context is lost and we are no
7536 // longer executing commands.
7537 if (*location != -1) {
7538 return error::kGenericError;
7539 }
[email protected]df37b9932013-03-08 05:21:427540 *location = program->GetAttribLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147541 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197542}
7543
[email protected]558847a2010-03-24 07:02:547544error::Error GLES2DecoderImpl::HandleGetAttribLocation(
[email protected]ed9f9cd2013-02-27 21:12:357545 uint32 immediate_data_size, const cmds::GetAttribLocation& c) {
[email protected]558847a2010-03-24 07:02:547546 uint32 name_size = c.data_size;
7547 const char* name = GetSharedMemoryAs<const char*>(
7548 c.name_shm_id, c.name_shm_offset, name_size);
7549 if (!name) {
7550 return error::kOutOfBounds;
7551 }
7552 String name_str(name, name_size);
7553 return GetAttribLocationHelper(
7554 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7555}
7556
[email protected]558847a2010-03-24 07:02:547557error::Error GLES2DecoderImpl::HandleGetAttribLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357558 uint32 immediate_data_size, const cmds::GetAttribLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547559 Bucket* bucket = GetBucket(c.name_bucket_id);
7560 if (!bucket) {
7561 return error::kInvalidArguments;
7562 }
7563 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187564 if (!bucket->GetAsString(&name_str)) {
7565 return error::kInvalidArguments;
7566 }
[email protected]558847a2010-03-24 07:02:547567 return GetAttribLocationHelper(
7568 c.program, c.location_shm_id, c.location_shm_offset, name_str);
7569}
7570
7571error::Error GLES2DecoderImpl::GetUniformLocationHelper(
7572 GLuint client_id, uint32 location_shm_id, uint32 location_shm_offset,
7573 const std::string& name_str) {
[email protected]258a3313f2011-10-18 20:13:577574 if (!StringIsValidForGLES(name_str.c_str())) {
[email protected]ab09b612013-03-11 22:11:517575 LOCAL_SET_GL_ERROR(
7576 GL_INVALID_VALUE, "glGetUniformLocation", "Invalid character");
[email protected]258a3313f2011-10-18 20:13:577577 return error::kNoError;
7578 }
[email protected]df37b9932013-03-08 05:21:427579 Program* program = GetProgramInfoNotShader(
[email protected]6b8cf1a2010-05-06 16:13:587580 client_id, "glUniformLocation");
[email protected]df37b9932013-03-08 05:21:427581 if (!program) {
[email protected]f7a64ee2010-02-01 22:24:147582 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197583 }
[email protected]df37b9932013-03-08 05:21:427584 if (!program->IsValid()) {
[email protected]ab09b612013-03-11 22:11:517585 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437586 GL_INVALID_OPERATION, "glGetUniformLocation", "program not linked");
[email protected]0bfd9882010-02-05 23:02:257587 return error::kNoError;
7588 }
[email protected]b9849abf2009-11-25 19:13:197589 GLint* location = GetSharedMemoryAs<GLint*>(
[email protected]558847a2010-03-24 07:02:547590 location_shm_id, location_shm_offset, sizeof(GLint));
7591 if (!location) {
[email protected]f7a64ee2010-02-01 22:24:147592 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197593 }
[email protected]558847a2010-03-24 07:02:547594 // Require the client to init this incase the context is lost an we are no
7595 // longer executing commands.
7596 if (*location != -1) {
7597 return error::kGenericError;
7598 }
[email protected]df37b9932013-03-08 05:21:427599 *location = program->GetUniformFakeLocation(name_str);
[email protected]f7a64ee2010-02-01 22:24:147600 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197601}
7602
[email protected]f7a64ee2010-02-01 22:24:147603error::Error GLES2DecoderImpl::HandleGetUniformLocation(
[email protected]ed9f9cd2013-02-27 21:12:357604 uint32 immediate_data_size, const cmds::GetUniformLocation& c) {
[email protected]b9849abf2009-11-25 19:13:197605 uint32 name_size = c.data_size;
7606 const char* name = GetSharedMemoryAs<const char*>(
7607 c.name_shm_id, c.name_shm_offset, name_size);
[email protected]558847a2010-03-24 07:02:547608 if (!name) {
[email protected]f7a64ee2010-02-01 22:24:147609 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:197610 }
7611 String name_str(name, name_size);
[email protected]558847a2010-03-24 07:02:547612 return GetUniformLocationHelper(
7613 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197614}
7615
[email protected]558847a2010-03-24 07:02:547616error::Error GLES2DecoderImpl::HandleGetUniformLocationBucket(
[email protected]ed9f9cd2013-02-27 21:12:357617 uint32 immediate_data_size, const cmds::GetUniformLocationBucket& c) {
[email protected]558847a2010-03-24 07:02:547618 Bucket* bucket = GetBucket(c.name_bucket_id);
7619 if (!bucket) {
7620 return error::kInvalidArguments;
7621 }
7622 std::string name_str;
[email protected]b1d2dcb2010-05-17 19:24:187623 if (!bucket->GetAsString(&name_str)) {
7624 return error::kInvalidArguments;
7625 }
[email protected]558847a2010-03-24 07:02:547626 return GetUniformLocationHelper(
7627 c.program, c.location_shm_id, c.location_shm_offset, name_str);
[email protected]b9849abf2009-11-25 19:13:197628}
7629
[email protected]ddd968b82010-03-02 00:44:297630error::Error GLES2DecoderImpl::HandleGetString(
[email protected]ed9f9cd2013-02-27 21:12:357631 uint32 immediate_data_size, const cmds::GetString& c) {
[email protected]ddd968b82010-03-02 00:44:297632 GLenum name = static_cast<GLenum>(c.name);
[email protected]9438b012010-06-15 22:55:057633 if (!validators_->string_type.IsValid(name)) {
[email protected]ab09b612013-03-11 22:11:517634 LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
[email protected]ddd968b82010-03-02 00:44:297635 return error::kNoError;
7636 }
[email protected]959e9072013-09-20 16:58:387637 const char* str = reinterpret_cast<const char*>(glGetString(name));
[email protected]f0d74742011-10-03 16:31:047638 std::string extensions;
[email protected]1958e0e2010-04-22 05:17:157639 switch (name) {
7640 case GL_VERSION:
7641 str = "OpenGL ES 2.0 Chromium";
7642 break;
7643 case GL_SHADING_LANGUAGE_VERSION:
7644 str = "OpenGL ES GLSL ES 1.0 Chromium";
7645 break;
[email protected]32939602012-05-09 06:25:167646 case GL_RENDERER:
[email protected]32939602012-05-09 06:25:167647 case GL_VENDOR:
[email protected]959e9072013-09-20 16:58:387648 // Return the unmasked VENDOR/RENDERER string for WebGL contexts.
7649 // They are used by WEBGL_debug_renderer_info.
7650 if (!force_webgl_glsl_validation_)
7651 str = "Chromium";
[email protected]32939602012-05-09 06:25:167652 break;
[email protected]1958e0e2010-04-22 05:17:157653 case GL_EXTENSIONS:
[email protected]f0d74742011-10-03 16:31:047654 {
[email protected]70dc60932013-06-04 03:33:497655 // For WebGL contexts, strip out the OES derivatives and
7656 // EXT frag depth extensions if they have not been enabled.
7657 if (force_webgl_glsl_validation_) {
[email protected]f0d74742011-10-03 16:31:047658 extensions = feature_info_->extensions();
[email protected]70dc60932013-06-04 03:33:497659 if (!derivatives_explicitly_enabled_) {
7660 size_t offset = extensions.find(kOESDerivativeExtension);
7661 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097662 extensions.replace(offset, arraysize(kOESDerivativeExtension),
[email protected]70dc60932013-06-04 03:33:497663 std::string());
7664 }
7665 }
7666 if (!frag_depth_explicitly_enabled_) {
7667 size_t offset = extensions.find(kEXTFragDepthExtension);
7668 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097669 extensions.replace(offset, arraysize(kEXTFragDepthExtension),
[email protected]70dc60932013-06-04 03:33:497670 std::string());
7671 }
[email protected]f0d74742011-10-03 16:31:047672 }
[email protected]aff39ac82013-06-08 04:53:137673 if (!draw_buffers_explicitly_enabled_) {
7674 size_t offset = extensions.find(kEXTDrawBuffersExtension);
7675 if (std::string::npos != offset) {
[email protected]f16cc9f2013-06-14 01:04:097676 extensions.replace(offset, arraysize(kEXTDrawBuffersExtension),
[email protected]aff39ac82013-06-08 04:53:137677 std::string());
7678 }
7679 }
[email protected]f0d74742011-10-03 16:31:047680 } else {
[email protected]6f5fac9d12012-06-26 21:02:457681 extensions = feature_info_->extensions().c_str();
[email protected]f0d74742011-10-03 16:31:047682 }
[email protected]6f5fac9d12012-06-26 21:02:457683 std::string surface_extensions = surface_->GetExtensions();
7684 if (!surface_extensions.empty())
7685 extensions += " " + surface_extensions;
7686 str = extensions.c_str();
[email protected]f0d74742011-10-03 16:31:047687 }
[email protected]1958e0e2010-04-22 05:17:157688 break;
7689 default:
[email protected]1958e0e2010-04-22 05:17:157690 break;
7691 }
[email protected]ddd968b82010-03-02 00:44:297692 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]1958e0e2010-04-22 05:17:157693 bucket->SetFromString(str);
[email protected]ddd968b82010-03-02 00:44:297694 return error::kNoError;
7695}
7696
[email protected]0c86dbf2010-03-05 08:14:117697error::Error GLES2DecoderImpl::HandleBufferData(
[email protected]ed9f9cd2013-02-27 21:12:357698 uint32 immediate_data_size, const cmds::BufferData& c) {
[email protected]0c86dbf2010-03-05 08:14:117699 GLenum target = static_cast<GLenum>(c.target);
7700 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
7701 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
7702 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
7703 GLenum usage = static_cast<GLenum>(c.usage);
7704 const void* data = NULL;
7705 if (data_shm_id != 0 || data_shm_offset != 0) {
7706 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
7707 if (!data) {
7708 return error::kOutOfBounds;
7709 }
7710 }
[email protected]0fbba3732013-07-17 15:40:137711 buffer_manager()->ValidateAndDoBufferData(&state_, target, size, data, usage);
[email protected]f7a64ee2010-02-01 22:24:147712 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:197713}
7714
[email protected]0c86dbf2010-03-05 08:14:117715void GLES2DecoderImpl::DoBufferSubData(
7716 GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) {
[email protected]0fbba3732013-07-17 15:40:137717 // Just delegate it. Some validation is actually done before this.
7718 buffer_manager()->ValidateAndDoBufferSubData(
7719 &state_, target, offset, size, data);
[email protected]b9849abf2009-11-25 19:13:197720}
7721
[email protected]0d6bfdc2011-11-02 01:32:207722bool GLES2DecoderImpl::ClearLevel(
7723 unsigned service_id,
7724 unsigned bind_target,
7725 unsigned target,
7726 int level,
7727 unsigned format,
7728 unsigned type,
7729 int width,
[email protected]4502e6492011-12-14 19:39:157730 int height,
7731 bool is_texture_immutable) {
[email protected]81375742012-06-08 00:04:007732 uint32 channels = GLES2Util::GetChannelsForFormat(format);
[email protected]345ba902013-11-14 21:39:007733 if (feature_info_->feature_flags().angle_depth_texture &&
7734 (channels & GLES2Util::kDepth) != 0) {
[email protected]81375742012-06-08 00:04:007735 // It's a depth format and ANGLE doesn't allow texImage2D or texSubImage2D
7736 // on depth formats.
7737 GLuint fb = 0;
7738 glGenFramebuffersEXT(1, &fb);
7739 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb);
7740
7741 bool have_stencil = (channels & GLES2Util::kStencil) != 0;
7742 GLenum attachment = have_stencil ? GL_DEPTH_STENCIL_ATTACHMENT :
7743 GL_DEPTH_ATTACHMENT;
7744
7745 glFramebufferTexture2DEXT(
7746 GL_DRAW_FRAMEBUFFER_EXT, attachment, target, service_id, level);
7747 // ANGLE promises a depth only attachment ok.
7748 if (glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER_EXT) !=
7749 GL_FRAMEBUFFER_COMPLETE) {
7750 return false;
7751 }
7752 glClearStencil(0);
7753 glStencilMask(-1);
7754 glClearDepth(1.0f);
7755 glDepthMask(true);
7756 glDisable(GL_SCISSOR_TEST);
7757 glClear(GL_DEPTH_BUFFER_BIT | (have_stencil ? GL_STENCIL_BUFFER_BIT : 0));
7758
7759 RestoreClearState();
7760
7761 glDeleteFramebuffersEXT(1, &fb);
[email protected]ed9f9cd2013-02-27 21:12:357762 Framebuffer* framebuffer =
[email protected]81375742012-06-08 00:04:007763 GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER_EXT);
7764 GLuint fb_service_id =
7765 framebuffer ? framebuffer->service_id() : GetBackbufferServiceId();
7766 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, fb_service_id);
7767 return true;
7768 }
7769
[email protected]45d15a62012-04-18 14:33:177770 static const uint32 kMaxZeroSize = 1024 * 1024 * 4;
7771
7772 uint32 size;
7773 uint32 padded_row_size;
[email protected]3458a64a2012-04-10 17:39:347774 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247775 width, height, format, type, state_.unpack_alignment, &size,
[email protected]45d15a62012-04-18 14:33:177776 NULL, &padded_row_size)) {
[email protected]0d6bfdc2011-11-02 01:32:207777 return false;
7778 }
[email protected]45d15a62012-04-18 14:33:177779
[email protected]a5d3dad2012-05-26 04:34:447780 TRACE_EVENT1("gpu", "GLES2DecoderImpl::ClearLevel", "size", size);
7781
[email protected]45d15a62012-04-18 14:33:177782 int tile_height;
7783
7784 if (size > kMaxZeroSize) {
7785 if (kMaxZeroSize < padded_row_size) {
7786 // That'd be an awfully large texture.
7787 return false;
7788 }
7789 // We should never have a large total size with a zero row size.
7790 DCHECK_GT(padded_row_size, 0U);
7791 tile_height = kMaxZeroSize / padded_row_size;
7792 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:247793 width, tile_height, format, type, state_.unpack_alignment, &size,
7794 NULL, NULL)) {
[email protected]45d15a62012-04-18 14:33:177795 return false;
7796 }
[email protected]4502e6492011-12-14 19:39:157797 } else {
[email protected]45d15a62012-04-18 14:33:177798 tile_height = height;
7799 }
7800
7801 // Assumes the size has already been checked.
[email protected]40d90a22013-04-09 03:39:557802 scoped_ptr<char[]> zero(new char[size]);
[email protected]45d15a62012-04-18 14:33:177803 memset(zero.get(), 0, size);
7804 glBindTexture(bind_target, service_id);
7805
7806 GLint y = 0;
7807 while (y < height) {
7808 GLint h = y + tile_height > height ? height - y : tile_height;
7809 if (is_texture_immutable || h != height) {
7810 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get());
7811 } else {
[email protected]8f1d2aa2013-05-10 23:45:387812 glTexImage2D(
[email protected]45d15a62012-04-18 14:33:177813 target, level, format, width, h, 0, format, type, zero.get());
7814 }
7815 y += tile_height;
[email protected]4502e6492011-12-14 19:39:157816 }
[email protected]c986af502013-08-14 01:04:447817 TextureRef* texture = texture_manager()->GetTextureInfoForTarget(
7818 &state_, bind_target);
[email protected]02965c22013-03-09 02:40:077819 glBindTexture(bind_target, texture ? texture->service_id() : 0);
[email protected]0d6bfdc2011-11-02 01:32:207820 return true;
7821}
7822
[email protected]ad84a3a2012-06-08 21:42:437823namespace {
7824
7825const int kS3TCBlockWidth = 4;
7826const int kS3TCBlockHeight = 4;
7827const int kS3TCDXT1BlockSize = 8;
7828const int kS3TCDXT3AndDXT5BlockSize = 16;
[email protected]2d3765b2012-10-03 00:31:077829const int kETC1BlockWidth = 4;
7830const int kETC1BlockHeight = 4;
7831const int kETC1BlockSize = 8;
[email protected]ad84a3a2012-06-08 21:42:437832
7833bool IsValidDXTSize(GLint level, GLsizei size) {
[email protected]10b56de2012-07-14 02:09:517834 return (size == 1) ||
7835 (size == 2) || !(size % kS3TCBlockWidth);
[email protected]ad84a3a2012-06-08 21:42:437836}
7837
7838} // anonymous namespace.
7839
7840bool GLES2DecoderImpl::ValidateCompressedTexFuncData(
7841 const char* function_name,
7842 GLsizei width, GLsizei height, GLenum format, size_t size) {
7843 unsigned int bytes_required = 0;
7844
7845 switch (format) {
7846 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7847 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: {
7848 int num_blocks_across =
7849 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7850 int num_blocks_down =
7851 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7852 int num_blocks = num_blocks_across * num_blocks_down;
7853 bytes_required = num_blocks * kS3TCDXT1BlockSize;
7854 break;
7855 }
7856 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7857 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7858 int num_blocks_across =
7859 (width + kS3TCBlockWidth - 1) / kS3TCBlockWidth;
7860 int num_blocks_down =
7861 (height + kS3TCBlockHeight - 1) / kS3TCBlockHeight;
7862 int num_blocks = num_blocks_across * num_blocks_down;
7863 bytes_required = num_blocks * kS3TCDXT3AndDXT5BlockSize;
7864 break;
7865 }
[email protected]2d3765b2012-10-03 00:31:077866 case GL_ETC1_RGB8_OES: {
7867 int num_blocks_across =
7868 (width + kETC1BlockWidth - 1) / kETC1BlockWidth;
7869 int num_blocks_down =
7870 (height + kETC1BlockHeight - 1) / kETC1BlockHeight;
7871 int num_blocks = num_blocks_across * num_blocks_down;
7872 bytes_required = num_blocks * kETC1BlockSize;
7873 break;
7874 }
[email protected]ad84a3a2012-06-08 21:42:437875 default:
[email protected]ab09b612013-03-11 22:11:517876 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]ad84a3a2012-06-08 21:42:437877 return false;
7878 }
7879
7880 if (size != bytes_required) {
[email protected]ab09b612013-03-11 22:11:517881 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437882 GL_INVALID_VALUE, function_name, "size is not correct for dimensions");
7883 return false;
7884 }
7885
7886 return true;
7887}
7888
7889bool GLES2DecoderImpl::ValidateCompressedTexDimensions(
7890 const char* function_name,
7891 GLint level, GLsizei width, GLsizei height, GLenum format) {
7892 switch (format) {
7893 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7894 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7895 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7896 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7897 if (!IsValidDXTSize(level, width) || !IsValidDXTSize(level, height)) {
[email protected]ab09b612013-03-11 22:11:517898 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437899 GL_INVALID_OPERATION, function_name,
7900 "width or height invalid for level");
7901 return false;
7902 }
7903 return true;
7904 }
[email protected]2d3765b2012-10-03 00:31:077905 case GL_ETC1_RGB8_OES:
7906 if (width <= 0 || height <= 0) {
[email protected]ab09b612013-03-11 22:11:517907 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077908 GL_INVALID_OPERATION, function_name,
7909 "width or height invalid for level");
7910 return false;
7911 }
7912 return true;
[email protected]ad84a3a2012-06-08 21:42:437913 default:
7914 return false;
7915 }
7916}
7917
7918bool GLES2DecoderImpl::ValidateCompressedTexSubDimensions(
7919 const char* function_name,
7920 GLenum target, GLint level, GLint xoffset, GLint yoffset,
7921 GLsizei width, GLsizei height, GLenum format,
[email protected]ed9f9cd2013-02-27 21:12:357922 Texture* texture) {
[email protected]ad84a3a2012-06-08 21:42:437923 if (xoffset < 0 || yoffset < 0) {
[email protected]ab09b612013-03-11 22:11:517924 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437925 GL_INVALID_VALUE, function_name, "xoffset or yoffset < 0");
7926 return false;
7927 }
7928
7929 switch (format) {
7930 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
7931 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
7932 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
7933 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
7934 const int kBlockWidth = 4;
7935 const int kBlockHeight = 4;
7936 if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
[email protected]ab09b612013-03-11 22:11:517937 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437938 GL_INVALID_OPERATION, function_name,
7939 "xoffset or yoffset not multiple of 4");
7940 return false;
7941 }
7942 GLsizei tex_width = 0;
7943 GLsizei tex_height = 0;
7944 if (!texture->GetLevelSize(target, level, &tex_width, &tex_height) ||
7945 width - xoffset > tex_width ||
7946 height - yoffset > tex_height) {
[email protected]ab09b612013-03-11 22:11:517947 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:437948 GL_INVALID_OPERATION, function_name, "dimensions out of range");
7949 return false;
7950 }
7951 return ValidateCompressedTexDimensions(
7952 function_name, level, width, height, format);
7953 }
[email protected]2d3765b2012-10-03 00:31:077954 case GL_ETC1_RGB8_OES: {
[email protected]ab09b612013-03-11 22:11:517955 LOCAL_SET_GL_ERROR(
[email protected]2d3765b2012-10-03 00:31:077956 GL_INVALID_OPERATION, function_name,
7957 "TexsubImage2d not supported for ECT1_RGB8_OES textures");
7958 return false;
7959 }
[email protected]ad84a3a2012-06-08 21:42:437960 default:
7961 return false;
7962 }
7963}
7964
[email protected]a93bb842010-02-16 23:03:477965error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
7966 GLenum target,
7967 GLint level,
7968 GLenum internal_format,
7969 GLsizei width,
7970 GLsizei height,
7971 GLint border,
7972 GLsizei image_size,
7973 const void* data) {
[email protected]a93bb842010-02-16 23:03:477974 // TODO(gman): Validate image_size is correct for width, height and format.
[email protected]9438b012010-06-15 22:55:057975 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:517976 LOCAL_SET_GL_ERROR_INVALID_ENUM(
7977 "glCompressedTexImage2D", target, "target");
[email protected]8eee29c2010-04-29 03:38:297978 return error::kNoError;
7979 }
[email protected]9438b012010-06-15 22:55:057980 if (!validators_->compressed_texture_format.IsValid(
7981 internal_format)) {
[email protected]ab09b612013-03-11 22:11:517982 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:537983 "glCompressedTexImage2D", internal_format, "internal_format");
[email protected]a93bb842010-02-16 23:03:477984 return error::kNoError;
7985 }
[email protected]80eb6b52012-01-19 00:14:417986 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]a93bb842010-02-16 23:03:477987 border != 0) {
[email protected]ab09b612013-03-11 22:11:517988 LOCAL_SET_GL_ERROR(
7989 GL_INVALID_VALUE,
7990 "glCompressedTexImage2D", "dimensions out of range");
[email protected]a93bb842010-02-16 23:03:477991 return error::kNoError;
7992 }
[email protected]c986af502013-08-14 01:04:447993 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
7994 &state_, target);
[email protected]370eaf12013-05-18 09:19:497995 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:517996 LOCAL_SET_GL_ERROR(
7997 GL_INVALID_VALUE,
7998 "glCompressedTexImage2D", "unknown texture target");
[email protected]a93bb842010-02-16 23:03:477999 return error::kNoError;
8000 }
[email protected]370eaf12013-05-18 09:19:498001 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078002 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518003 LOCAL_SET_GL_ERROR(
8004 GL_INVALID_OPERATION,
8005 "glCompressedTexImage2D", "texture is immutable");
[email protected]ad84a3a2012-06-08 21:42:438006 return error::kNoError;
8007 }
8008
8009 if (!ValidateCompressedTexDimensions(
8010 "glCompressedTexImage2D", level, width, height, internal_format) ||
8011 !ValidateCompressedTexFuncData(
8012 "glCompressedTexImage2D", width, height, internal_format, image_size)) {
[email protected]97dc7cbe2011-12-06 17:26:178013 return error::kNoError;
8014 }
[email protected]968351b2011-12-20 08:26:518015
[email protected]7989c9e2013-01-23 06:39:268016 if (!EnsureGPUMemoryAvailable(image_size)) {
[email protected]ab09b612013-03-11 22:11:518017 LOCAL_SET_GL_ERROR(
8018 GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory");
[email protected]7989c9e2013-01-23 06:39:268019 return error::kNoError;
8020 }
8021
[email protected]02965c22013-03-09 02:40:078022 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448023 framebuffer_state_.clear_state_dirty = true;
[email protected]968351b2011-12-20 08:26:518024 }
8025
[email protected]40d90a22013-04-09 03:39:558026 scoped_ptr<int8[]> zero;
[email protected]a93bb842010-02-16 23:03:478027 if (!data) {
8028 zero.reset(new int8[image_size]);
8029 memset(zero.get(), 0, image_size);
8030 data = zero.get();
8031 }
[email protected]ab09b612013-03-11 22:11:518032 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedTexImage2D");
[email protected]a93bb842010-02-16 23:03:478033 glCompressedTexImage2D(
8034 target, level, internal_format, width, height, border, image_size, data);
[email protected]ab09b612013-03-11 22:11:518035 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438036 if (error == GL_NO_ERROR) {
8037 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498038 texture_ref, target, level, internal_format,
8039 width, height, 1, border, 0, 0, true);
[email protected]cadde4a2010-07-31 17:10:438040 }
[email protected]a93bb842010-02-16 23:03:478041 return error::kNoError;
8042}
8043
[email protected]f7a64ee2010-02-01 22:24:148044error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358045 uint32 immediate_data_size, const cmds::CompressedTexImage2D& c) {
[email protected]b9849abf2009-11-25 19:13:198046 GLenum target = static_cast<GLenum>(c.target);
8047 GLint level = static_cast<GLint>(c.level);
8048 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8049 GLsizei width = static_cast<GLsizei>(c.width);
8050 GLsizei height = static_cast<GLsizei>(c.height);
8051 GLint border = static_cast<GLint>(c.border);
8052 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
8053 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
8054 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
8055 const void* data = NULL;
8056 if (data_shm_id != 0 || data_shm_offset != 0) {
8057 data = GetSharedMemoryAs<const void*>(
8058 data_shm_id, data_shm_offset, image_size);
[email protected]ba3176a2009-12-16 18:19:468059 if (!data) {
[email protected]f7a64ee2010-02-01 22:24:148060 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198061 }
8062 }
[email protected]a93bb842010-02-16 23:03:478063 return DoCompressedTexImage2D(
[email protected]b9849abf2009-11-25 19:13:198064 target, level, internal_format, width, height, border, image_size, data);
[email protected]b9849abf2009-11-25 19:13:198065}
8066
[email protected]b6140d02010-05-17 14:47:168067error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
[email protected]ed9f9cd2013-02-27 21:12:358068 uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:168069 GLenum target = static_cast<GLenum>(c.target);
8070 GLint level = static_cast<GLint>(c.level);
8071 GLenum internal_format = static_cast<GLenum>(c.internalformat);
8072 GLsizei width = static_cast<GLsizei>(c.width);
8073 GLsizei height = static_cast<GLsizei>(c.height);
8074 GLint border = static_cast<GLint>(c.border);
8075 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288076 if (!bucket) {
8077 return error::kInvalidArguments;
8078 }
8079 uint32 data_size = bucket->size();
8080 GLsizei imageSize = data_size;
8081 const void* data = bucket->GetData(0, data_size);
8082 if (!data) {
8083 return error::kInvalidArguments;
8084 }
[email protected]b6140d02010-05-17 14:47:168085 return DoCompressedTexImage2D(
8086 target, level, internal_format, width, height, border,
[email protected]12f93d82011-10-17 21:16:288087 imageSize, data);
[email protected]b6140d02010-05-17 14:47:168088}
8089
8090error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
8091 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:358092 const cmds::CompressedTexSubImage2DBucket& c) {
[email protected]b6140d02010-05-17 14:47:168093 GLenum target = static_cast<GLenum>(c.target);
8094 GLint level = static_cast<GLint>(c.level);
8095 GLint xoffset = static_cast<GLint>(c.xoffset);
8096 GLint yoffset = static_cast<GLint>(c.yoffset);
8097 GLsizei width = static_cast<GLsizei>(c.width);
8098 GLsizei height = static_cast<GLsizei>(c.height);
8099 GLenum format = static_cast<GLenum>(c.format);
8100 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:288101 if (!bucket) {
8102 return error::kInvalidArguments;
8103 }
[email protected]b6140d02010-05-17 14:47:168104 uint32 data_size = bucket->size();
8105 GLsizei imageSize = data_size;
8106 const void* data = bucket->GetData(0, data_size);
[email protected]12f93d82011-10-17 21:16:288107 if (!data) {
8108 return error::kInvalidArguments;
8109 }
[email protected]9438b012010-06-15 22:55:058110 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518111 LOCAL_SET_GL_ERROR(
[email protected]f80e6e12012-08-31 00:43:538112 GL_INVALID_ENUM, "glCompressedTexSubImage2D", "target");
[email protected]b6140d02010-05-17 14:47:168113 return error::kNoError;
8114 }
[email protected]9438b012010-06-15 22:55:058115 if (!validators_->compressed_texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518116 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8117 "glCompressedTexSubImage2D", format, "format");
[email protected]9438b012010-06-15 22:55:058118 return error::kNoError;
8119 }
[email protected]b6140d02010-05-17 14:47:168120 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518121 LOCAL_SET_GL_ERROR(
8122 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "width < 0");
[email protected]b6140d02010-05-17 14:47:168123 return error::kNoError;
8124 }
8125 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518126 LOCAL_SET_GL_ERROR(
8127 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "height < 0");
[email protected]b6140d02010-05-17 14:47:168128 return error::kNoError;
8129 }
8130 if (imageSize < 0) {
[email protected]ab09b612013-03-11 22:11:518131 LOCAL_SET_GL_ERROR(
8132 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "imageSize < 0");
[email protected]b6140d02010-05-17 14:47:168133 return error::kNoError;
8134 }
[email protected]cadde4a2010-07-31 17:10:438135 DoCompressedTexSubImage2D(
[email protected]b6140d02010-05-17 14:47:168136 target, level, xoffset, yoffset, width, height, format, imageSize, data);
8137 return error::kNoError;
8138}
8139
[email protected]f7a64ee2010-02-01 22:24:148140error::Error GLES2DecoderImpl::HandleTexImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358141 uint32 immediate_data_size, const cmds::TexImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388142 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexImage2D");
[email protected]c986af502013-08-14 01:04:448143 // Set as failed for now, but if it successed, this will be set to not failed.
8144 texture_state_.tex_image_2d_failed = true;
[email protected]b9849abf2009-11-25 19:13:198145 GLenum target = static_cast<GLenum>(c.target);
8146 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:448147 // TODO(kloveless): Change TexImage2D command to use unsigned integer
8148 // for internalformat.
8149 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]b9849abf2009-11-25 19:13:198150 GLsizei width = static_cast<GLsizei>(c.width);
8151 GLsizei height = static_cast<GLsizei>(c.height);
8152 GLint border = static_cast<GLint>(c.border);
8153 GLenum format = static_cast<GLenum>(c.format);
8154 GLenum type = static_cast<GLenum>(c.type);
8155 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
8156 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
[email protected]a76b0052010-03-05 00:33:188157 uint32 pixels_size;
[email protected]3458a64a2012-04-10 17:39:348158 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248159 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
[email protected]3458a64a2012-04-10 17:39:348160 NULL)) {
[email protected]a76b0052010-03-05 00:33:188161 return error::kOutOfBounds;
8162 }
[email protected]b9849abf2009-11-25 19:13:198163 const void* pixels = NULL;
8164 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
8165 pixels = GetSharedMemoryAs<const void*>(
8166 pixels_shm_id, pixels_shm_offset, pixels_size);
[email protected]ba3176a2009-12-16 18:19:468167 if (!pixels) {
[email protected]f7a64ee2010-02-01 22:24:148168 return error::kOutOfBounds;
[email protected]b9849abf2009-11-25 19:13:198169 }
8170 }
[email protected]f598f422012-12-07 08:30:038171
[email protected]c986af502013-08-14 01:04:448172 TextureManager::DoTextImage2DArguments args = {
8173 target, level, internal_format, width, height, border, format, type,
8174 pixels, pixels_size};
8175 texture_manager()->ValidateAndDoTexImage2D(
8176 &texture_state_, &state_, &framebuffer_state_, args);
[email protected]f598f422012-12-07 08:30:038177 return error::kNoError;
[email protected]b9849abf2009-11-25 19:13:198178}
8179
[email protected]cadde4a2010-07-31 17:10:438180void GLES2DecoderImpl::DoCompressedTexSubImage2D(
8181 GLenum target,
8182 GLint level,
8183 GLint xoffset,
8184 GLint yoffset,
8185 GLsizei width,
8186 GLsizei height,
8187 GLenum format,
8188 GLsizei image_size,
8189 const void * data) {
[email protected]c986af502013-08-14 01:04:448190 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8191 &state_, target);
[email protected]370eaf12013-05-18 09:19:498192 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518193 LOCAL_SET_GL_ERROR(
8194 GL_INVALID_OPERATION,
8195 "glCompressedTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438196 return;
8197 }
[email protected]370eaf12013-05-18 09:19:498198 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438199 GLenum type = 0;
[email protected]df6cf1ad2011-01-29 01:20:528200 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078201 if (!texture->GetLevelType(target, level, &type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518202 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528203 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438204 "glCompressedTexSubImage2D", "level does not exist.");
[email protected]df6cf1ad2011-01-29 01:20:528205 return;
8206 }
8207 if (internal_format != format) {
[email protected]ab09b612013-03-11 22:11:518208 LOCAL_SET_GL_ERROR(
[email protected]df6cf1ad2011-01-29 01:20:528209 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438210 "glCompressedTexSubImage2D", "format does not match internal format.");
[email protected]df6cf1ad2011-01-29 01:20:528211 return;
8212 }
[email protected]02965c22013-03-09 02:40:078213 if (!texture->ValidForTexture(
[email protected]df6cf1ad2011-01-29 01:20:528214 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518215 LOCAL_SET_GL_ERROR(
8216 GL_INVALID_VALUE, "glCompressedTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438217 return;
8218 }
[email protected]ad84a3a2012-06-08 21:42:438219
8220 if (!ValidateCompressedTexFuncData(
8221 "glCompressedTexSubImage2D", width, height, format, image_size) ||
8222 !ValidateCompressedTexSubDimensions(
8223 "glCompressedTexSubImage2D",
[email protected]02965c22013-03-09 02:40:078224 target, level, xoffset, yoffset, width, height, format, texture)) {
[email protected]ad84a3a2012-06-08 21:42:438225 return;
8226 }
8227
8228
[email protected]0d6bfdc2011-11-02 01:32:208229 // Note: There is no need to deal with texture cleared tracking here
8230 // because the validation above means you can only get here if the level
8231 // is already a matching compressed format and in that case
8232 // CompressedTexImage2D already cleared the texture.
[email protected]cadde4a2010-07-31 17:10:438233 glCompressedTexSubImage2D(
8234 target, level, xoffset, yoffset, width, height, format, image_size, data);
8235}
8236
[email protected]6e288612010-12-21 20:45:038237static void Clip(
8238 GLint start, GLint range, GLint sourceRange,
8239 GLint* out_start, GLint* out_range) {
8240 DCHECK(out_start);
8241 DCHECK(out_range);
8242 if (start < 0) {
8243 range += start;
8244 start = 0;
8245 }
8246 GLint end = start + range;
8247 if (end > sourceRange) {
8248 range -= end - sourceRange;
8249 }
8250 *out_start = start;
8251 *out_range = range;
8252}
8253
[email protected]cadde4a2010-07-31 17:10:438254void GLES2DecoderImpl::DoCopyTexImage2D(
[email protected]a5d3dad2012-05-26 04:34:448255 GLenum target,
8256 GLint level,
8257 GLenum internal_format,
8258 GLint x,
8259 GLint y,
8260 GLsizei width,
8261 GLsizei height,
8262 GLint border) {
[email protected]09e17272012-11-30 10:30:448263 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448264 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8265 &state_, target);
[email protected]370eaf12013-05-18 09:19:498266 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518267 LOCAL_SET_GL_ERROR(
8268 GL_INVALID_OPERATION,
8269 "glCopyTexImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438270 return;
8271 }
[email protected]370eaf12013-05-18 09:19:498272 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:078273 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:518274 LOCAL_SET_GL_ERROR(
8275 GL_INVALID_OPERATION, "glCopyTexImage2D", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:178276 }
[email protected]80eb6b52012-01-19 00:14:418277 if (!texture_manager()->ValidForTarget(target, level, width, height, 1) ||
[email protected]f5719fb2010-08-04 18:27:188278 border != 0) {
[email protected]ab09b612013-03-11 22:11:518279 LOCAL_SET_GL_ERROR(
8280 GL_INVALID_VALUE, "glCopyTexImage2D", "dimensions out of range");
[email protected]f5719fb2010-08-04 18:27:188281 return;
8282 }
[email protected]c986af502013-08-14 01:04:448283 if (!texture_manager()->ValidateTextureParameters(
8284 state_.GetErrorState(), "glCopyTexImage2D", target, internal_format,
8285 GL_UNSIGNED_BYTE, level)) {
[email protected]81375742012-06-08 00:04:008286 return;
8287 }
[email protected]f5719fb2010-08-04 18:27:188288
[email protected]9edc6b22010-12-23 02:00:268289 // Check we have compatible formats.
8290 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8291 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8292 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format);
8293
8294 if ((channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518295 LOCAL_SET_GL_ERROR(
8296 GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268297 return;
8298 }
8299
[email protected]81375742012-06-08 00:04:008300 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518301 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008302 GL_INVALID_OPERATION,
[email protected]7989c9e2013-01-23 06:39:268303 "glCopyTexImage2D", "can not be used with depth or stencil textures");
8304 return;
8305 }
8306
8307 uint32 estimated_size = 0;
8308 if (!GLES2Util::ComputeImageDataSizes(
8309 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment,
8310 &estimated_size, NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518311 LOCAL_SET_GL_ERROR(
8312 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:268313 return;
8314 }
8315
8316 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:518317 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory");
[email protected]81375742012-06-08 00:04:008318 return;
8319 }
8320
[email protected]a0b78dc2011-11-11 10:43:108321 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) {
8322 return;
8323 }
8324
[email protected]ab09b612013-03-11 22:11:518325 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTexImage2D");
[email protected]de26b3c2011-08-03 21:54:278326 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038327 gfx::Size size = GetBoundReadFrameBufferSize();
[email protected]9edc6b22010-12-23 02:00:268328
[email protected]02965c22013-03-09 02:40:078329 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:448330 framebuffer_state_.clear_state_dirty = true;
[email protected]297ca1c2011-06-20 23:08:468331 }
8332
[email protected]9edc6b22010-12-23 02:00:268333 // Clip to size to source dimensions
[email protected]6e288612010-12-21 20:45:038334 GLint copyX = 0;
8335 GLint copyY = 0;
8336 GLint copyWidth = 0;
8337 GLint copyHeight = 0;
8338 Clip(x, width, size.width(), &copyX, &copyWidth);
8339 Clip(y, height, size.height(), &copyY, &copyHeight);
8340
8341 if (copyX != x ||
8342 copyY != y ||
8343 copyWidth != width ||
8344 copyHeight != height) {
8345 // some part was clipped so clear the texture.
[email protected]0d6bfdc2011-11-02 01:32:208346 if (!ClearLevel(
[email protected]02965c22013-03-09 02:40:078347 texture->service_id(), texture->target(),
[email protected]4502e6492011-12-14 19:39:158348 target, level, internal_format, GL_UNSIGNED_BYTE, width, height,
[email protected]02965c22013-03-09 02:40:078349 texture->IsImmutable())) {
[email protected]ab09b612013-03-11 22:11:518350 LOCAL_SET_GL_ERROR(
8351 GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too big");
[email protected]6e288612010-12-21 20:45:038352 return;
8353 }
[email protected]6e288612010-12-21 20:45:038354 if (copyHeight > 0 && copyWidth > 0) {
8355 GLint dx = copyX - x;
8356 GLint dy = copyY - y;
8357 GLint destX = dx;
8358 GLint destY = dy;
8359 glCopyTexSubImage2D(target, level,
8360 destX, destY, copyX, copyY,
8361 copyWidth, copyHeight);
8362 }
8363 } else {
8364 glCopyTexImage2D(target, level, internal_format,
8365 copyX, copyY, copyWidth, copyHeight, border);
8366 }
[email protected]ab09b612013-03-11 22:11:518367 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTexImage2D");
[email protected]cadde4a2010-07-31 17:10:438368 if (error == GL_NO_ERROR) {
8369 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:498370 texture_ref, target, level, internal_format, width, height, 1,
[email protected]0d6bfdc2011-11-02 01:32:208371 border, internal_format, GL_UNSIGNED_BYTE, true);
[email protected]cadde4a2010-07-31 17:10:438372 }
8373}
8374
8375void GLES2DecoderImpl::DoCopyTexSubImage2D(
[email protected]a5d3dad2012-05-26 04:34:448376 GLenum target,
8377 GLint level,
8378 GLint xoffset,
8379 GLint yoffset,
8380 GLint x,
8381 GLint y,
8382 GLsizei width,
8383 GLsizei height) {
[email protected]09e17272012-11-30 10:30:448384 DCHECK(!ShouldDeferReads());
[email protected]c986af502013-08-14 01:04:448385 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8386 &state_, target);
[email protected]370eaf12013-05-18 09:19:498387 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518388 LOCAL_SET_GL_ERROR(
8389 GL_INVALID_OPERATION,
8390 "glCopyTexSubImage2D", "unknown texture for target");
[email protected]cadde4a2010-07-31 17:10:438391 return;
8392 }
[email protected]370eaf12013-05-18 09:19:498393 Texture* texture = texture_ref->texture();
[email protected]cadde4a2010-07-31 17:10:438394 GLenum type = 0;
8395 GLenum format = 0;
[email protected]02965c22013-03-09 02:40:078396 if (!texture->GetLevelType(target, level, &type, &format) ||
8397 !texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438398 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518399 LOCAL_SET_GL_ERROR(
8400 GL_INVALID_VALUE, "glCopyTexSubImage2D", "bad dimensions.");
[email protected]cadde4a2010-07-31 17:10:438401 return;
8402 }
[email protected]85a4ac22013-05-31 01:58:478403 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518404 LOCAL_SET_GL_ERROR(
8405 GL_INVALID_OPERATION,
8406 "glCopyTexSubImage2D", "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598407 return;
8408 }
[email protected]9edc6b22010-12-23 02:00:268409
8410 // Check we have compatible formats.
8411 GLenum read_format = GetBoundReadFrameBufferInternalFormat();
8412 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format);
8413 uint32 channels_needed = GLES2Util::GetChannelsForFormat(format);
8414
[email protected]2d3765b2012-10-03 00:31:078415 if (!channels_needed ||
8416 (channels_needed & channels_exist) != channels_needed) {
[email protected]ab09b612013-03-11 22:11:518417 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438418 GL_INVALID_OPERATION, "glCopyTexSubImage2D", "incompatible format");
[email protected]9edc6b22010-12-23 02:00:268419 return;
8420 }
8421
[email protected]81375742012-06-08 00:04:008422 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518423 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008424 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:438425 "glCopySubImage2D", "can not be used with depth or stencil textures");
[email protected]81375742012-06-08 00:04:008426 return;
8427 }
8428
[email protected]a0b78dc2011-11-11 10:43:108429 if (!CheckBoundFramebuffersValid("glCopyTexSubImage2D")) {
8430 return;
8431 }
8432
[email protected]de26b3c2011-08-03 21:54:278433 ScopedResolvedFrameBufferBinder binder(this, false, true);
[email protected]6e288612010-12-21 20:45:038434 gfx::Size size = GetBoundReadFrameBufferSize();
8435 GLint copyX = 0;
8436 GLint copyY = 0;
8437 GLint copyWidth = 0;
8438 GLint copyHeight = 0;
8439 Clip(x, width, size.width(), &copyX, &copyWidth);
8440 Clip(y, height, size.height(), &copyY, &copyHeight);
[email protected]0d6bfdc2011-11-02 01:32:208441
[email protected]370eaf12013-05-18 09:19:498442 if (!texture_manager()->ClearTextureLevel(this, texture_ref, target, level)) {
[email protected]ab09b612013-03-11 22:11:518443 LOCAL_SET_GL_ERROR(
8444 GL_OUT_OF_MEMORY, "glCopyTexSubImage2D", "dimensions too big");
[email protected]0d6bfdc2011-11-02 01:32:208445 return;
8446 }
8447
[email protected]6e288612010-12-21 20:45:038448 if (copyX != x ||
8449 copyY != y ||
8450 copyWidth != width ||
8451 copyHeight != height) {
[email protected]0d6bfdc2011-11-02 01:32:208452 // some part was clipped so clear the sub rect.
[email protected]6e288612010-12-21 20:45:038453 uint32 pixels_size = 0;
[email protected]3458a64a2012-04-10 17:39:348454 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248455 width, height, format, type, state_.unpack_alignment, &pixels_size,
8456 NULL, NULL)) {
[email protected]ab09b612013-03-11 22:11:518457 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:438458 GL_INVALID_VALUE, "glCopyTexSubImage2D", "dimensions too large");
[email protected]6e288612010-12-21 20:45:038459 return;
8460 }
[email protected]40d90a22013-04-09 03:39:558461 scoped_ptr<char[]> zero(new char[pixels_size]);
[email protected]6e288612010-12-21 20:45:038462 memset(zero.get(), 0, pixels_size);
8463 glTexSubImage2D(
8464 target, level, xoffset, yoffset, width, height,
8465 format, type, zero.get());
8466 }
[email protected]0d6bfdc2011-11-02 01:32:208467
[email protected]6e288612010-12-21 20:45:038468 if (copyHeight > 0 && copyWidth > 0) {
8469 GLint dx = copyX - x;
8470 GLint dy = copyY - y;
8471 GLint destX = xoffset + dx;
8472 GLint destY = yoffset + dy;
8473 glCopyTexSubImage2D(target, level,
8474 destX, destY, copyX, copyY,
8475 copyWidth, copyHeight);
8476 }
[email protected]cadde4a2010-07-31 17:10:438477}
8478
[email protected]f598f422012-12-07 08:30:038479bool GLES2DecoderImpl::ValidateTexSubImage2D(
8480 error::Error* error,
8481 const char* function_name,
8482 GLenum target,
8483 GLint level,
8484 GLint xoffset,
8485 GLint yoffset,
8486 GLsizei width,
8487 GLsizei height,
8488 GLenum format,
8489 GLenum type,
8490 const void * data) {
8491 (*error) = error::kNoError;
8492 if (!validators_->texture_target.IsValid(target)) {
[email protected]ab09b612013-03-11 22:11:518493 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]f598f422012-12-07 08:30:038494 return false;
8495 }
8496 if (width < 0) {
[email protected]ab09b612013-03-11 22:11:518497 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "width < 0");
[email protected]f598f422012-12-07 08:30:038498 return false;
8499 }
8500 if (height < 0) {
[email protected]ab09b612013-03-11 22:11:518501 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "height < 0");
[email protected]f598f422012-12-07 08:30:038502 return false;
8503 }
8504 if (!validators_->texture_format.IsValid(format)) {
[email protected]ab09b612013-03-11 22:11:518505 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, format, "format");
[email protected]f598f422012-12-07 08:30:038506 return false;
8507 }
8508 if (!validators_->pixel_type.IsValid(type)) {
[email protected]ab09b612013-03-11 22:11:518509 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, type, "type");
[email protected]f598f422012-12-07 08:30:038510 return false;
8511 }
[email protected]c986af502013-08-14 01:04:448512 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8513 &state_, target);
[email protected]370eaf12013-05-18 09:19:498514 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:518515 LOCAL_SET_GL_ERROR(
8516 GL_INVALID_OPERATION,
8517 function_name, "unknown texture for target");
[email protected]f598f422012-12-07 08:30:038518 return false;
[email protected]cadde4a2010-07-31 17:10:438519 }
[email protected]370eaf12013-05-18 09:19:498520 Texture* texture = texture_ref->texture();
[email protected]df6cf1ad2011-01-29 01:20:528521 GLenum current_type = 0;
8522 GLenum internal_format = 0;
[email protected]02965c22013-03-09 02:40:078523 if (!texture->GetLevelType(target, level, &current_type, &internal_format)) {
[email protected]ab09b612013-03-11 22:11:518524 LOCAL_SET_GL_ERROR(
[email protected]f598f422012-12-07 08:30:038525 GL_INVALID_OPERATION, function_name, "level does not exist.");
8526 return false;
[email protected]df6cf1ad2011-01-29 01:20:528527 }
8528 if (format != internal_format) {
[email protected]ab09b612013-03-11 22:11:518529 LOCAL_SET_GL_ERROR(
8530 GL_INVALID_OPERATION,
8531 function_name, "format does not match internal format.");
[email protected]f598f422012-12-07 08:30:038532 return false;
[email protected]df6cf1ad2011-01-29 01:20:528533 }
8534 if (type != current_type) {
[email protected]ab09b612013-03-11 22:11:518535 LOCAL_SET_GL_ERROR(
8536 GL_INVALID_OPERATION,
8537 function_name, "type does not match type of texture.");
[email protected]f598f422012-12-07 08:30:038538 return false;
[email protected]df6cf1ad2011-01-29 01:20:528539 }
[email protected]85a4ac22013-05-31 01:58:478540 if (async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:518541 LOCAL_SET_GL_ERROR(
8542 GL_INVALID_OPERATION,
8543 function_name, "async upload pending for texture");
[email protected]32145a92012-12-17 09:01:598544 return false;
8545 }
[email protected]02965c22013-03-09 02:40:078546 if (!texture->ValidForTexture(
[email protected]cadde4a2010-07-31 17:10:438547 target, level, xoffset, yoffset, width, height, format, type)) {
[email protected]ab09b612013-03-11 22:11:518548 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "bad dimensions.");
[email protected]f598f422012-12-07 08:30:038549 return false;
[email protected]cadde4a2010-07-31 17:10:438550 }
[email protected]81375742012-06-08 00:04:008551 if ((GLES2Util::GetChannelsForFormat(format) &
8552 (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) {
[email protected]ab09b612013-03-11 22:11:518553 LOCAL_SET_GL_ERROR(
[email protected]81375742012-06-08 00:04:008554 GL_INVALID_OPERATION,
[email protected]f598f422012-12-07 08:30:038555 function_name, "can not supply data for depth or stencil textures");
8556 return false;
[email protected]81375742012-06-08 00:04:008557 }
[email protected]f598f422012-12-07 08:30:038558 if (data == NULL) {
8559 (*error) = error::kOutOfBounds;
8560 return false;
8561 }
8562 return true;
8563}
[email protected]81375742012-06-08 00:04:008564
[email protected]f598f422012-12-07 08:30:038565error::Error GLES2DecoderImpl::DoTexSubImage2D(
8566 GLenum target,
8567 GLint level,
8568 GLint xoffset,
8569 GLint yoffset,
8570 GLsizei width,
8571 GLsizei height,
8572 GLenum format,
8573 GLenum type,
8574 const void * data) {
8575 error::Error error = error::kNoError;
8576 if (!ValidateTexSubImage2D(&error, "glTexSubImage2D", target, level,
8577 xoffset, yoffset, width, height, format, type, data)) {
8578 return error;
8579 }
[email protected]c986af502013-08-14 01:04:448580 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
8581 &state_, target);
[email protected]370eaf12013-05-18 09:19:498582 Texture* texture = texture_ref->texture();
[email protected]4502e6492011-12-14 19:39:158583 GLsizei tex_width = 0;
8584 GLsizei tex_height = 0;
[email protected]02965c22013-03-09 02:40:078585 bool ok = texture->GetLevelSize(target, level, &tex_width, &tex_height);
[email protected]4502e6492011-12-14 19:39:158586 DCHECK(ok);
8587 if (xoffset != 0 || yoffset != 0 ||
8588 width != tex_width || height != tex_height) {
[email protected]370eaf12013-05-18 09:19:498589 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
8590 target, level)) {
[email protected]ab09b612013-03-11 22:11:518591 LOCAL_SET_GL_ERROR(
8592 GL_OUT_OF_MEMORY, "glTexSubImage2D", "dimensions too big");
[email protected]f598f422012-12-07 08:30:038593 return error::kNoError;
[email protected]473c01ccb2011-06-07 01:33:308594 }
[email protected]c986af502013-08-14 01:04:448595 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158596 glTexSubImage2D(
8597 target, level, xoffset, yoffset, width, height, format, type, data);
[email protected]f598f422012-12-07 08:30:038598 return error::kNoError;
[email protected]0d6bfdc2011-11-02 01:32:208599 }
[email protected]4502e6492011-12-14 19:39:158600
[email protected]345ba902013-11-14 21:39:008601 if (!texture_state_.texsubimage2d_faster_than_teximage2d &&
[email protected]c986af502013-08-14 01:04:448602 !texture->IsImmutable()) {
8603 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158604 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the
8605 // same as internal_foramt. If that changes we'll need to look them up.
[email protected]8f1d2aa2013-05-10 23:45:388606 glTexImage2D(
[email protected]4502e6492011-12-14 19:39:158607 target, level, format, width, height, 0, format, type, data);
8608 } else {
[email protected]c986af502013-08-14 01:04:448609 ScopedTextureUploadTimer timer(&texture_state_);
[email protected]4502e6492011-12-14 19:39:158610 glTexSubImage2D(
8611 target, level, xoffset, yoffset, width, height, format, type, data);
8612 }
[email protected]370eaf12013-05-18 09:19:498613 texture_manager()->SetLevelCleared(texture_ref, target, level, true);
[email protected]f598f422012-12-07 08:30:038614 return error::kNoError;
[email protected]cadde4a2010-07-31 17:10:438615}
8616
[email protected]b493ee622011-04-13 23:52:008617error::Error GLES2DecoderImpl::HandleTexSubImage2D(
[email protected]ed9f9cd2013-02-27 21:12:358618 uint32 immediate_data_size, const cmds::TexSubImage2D& c) {
[email protected]43ed3a72012-05-30 22:55:388619 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D");
[email protected]b493ee622011-04-13 23:52:008620 GLboolean internal = static_cast<GLboolean>(c.internal);
[email protected]c986af502013-08-14 01:04:448621 if (internal == GL_TRUE && texture_state_.tex_image_2d_failed)
[email protected]b493ee622011-04-13 23:52:008622 return error::kNoError;
8623
8624 GLenum target = static_cast<GLenum>(c.target);
8625 GLint level = static_cast<GLint>(c.level);
8626 GLint xoffset = static_cast<GLint>(c.xoffset);
8627 GLint yoffset = static_cast<GLint>(c.yoffset);
8628 GLsizei width = static_cast<GLsizei>(c.width);
8629 GLsizei height = static_cast<GLsizei>(c.height);
8630 GLenum format = static_cast<GLenum>(c.format);
8631 GLenum type = static_cast<GLenum>(c.type);
8632 uint32 data_size;
[email protected]3458a64a2012-04-10 17:39:348633 if (!GLES2Util::ComputeImageDataSizes(
[email protected]e259eb412012-10-13 05:47:248634 width, height, format, type, state_.unpack_alignment, &data_size,
8635 NULL, NULL)) {
[email protected]b493ee622011-04-13 23:52:008636 return error::kOutOfBounds;
8637 }
8638 const void* pixels = GetSharedMemoryAs<const void*>(
8639 c.pixels_shm_id, c.pixels_shm_offset, data_size);
[email protected]f598f422012-12-07 08:30:038640 return DoTexSubImage2D(
[email protected]b493ee622011-04-13 23:52:008641 target, level, xoffset, yoffset, width, height, format, type, pixels);
[email protected]b493ee622011-04-13 23:52:008642}
8643
[email protected]f7a64ee2010-02-01 22:24:148644error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
[email protected]ed9f9cd2013-02-27 21:12:358645 uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) {
[email protected]8bf5a3e2010-01-29 04:21:368646 GLuint index = static_cast<GLuint>(c.index);
8647 GLenum pname = static_cast<GLenum>(c.pname);
[email protected]ed9f9cd2013-02-27 21:12:358648 typedef cmds::GetVertexAttribPointerv::Result Result;
[email protected]0bfd9882010-02-05 23:02:258649 Result* result = GetSharedMemoryAs<Result*>(
8650 c.pointer_shm_id, c.pointer_shm_offset, Result::ComputeSize(1));
[email protected]8bf5a3e2010-01-29 04:21:368651 if (!result) {
[email protected]f7a64ee2010-02-01 22:24:148652 return error::kOutOfBounds;
[email protected]8bf5a3e2010-01-29 04:21:368653 }
[email protected]07d0cc82010-02-17 04:51:408654 // Check that the client initialized the result.
8655 if (result->size != 0) {
8656 return error::kInvalidArguments;
8657 }
[email protected]9438b012010-06-15 22:55:058658 if (!validators_->vertex_pointer.IsValid(pname)) {
[email protected]ab09b612013-03-11 22:11:518659 LOCAL_SET_GL_ERROR_INVALID_ENUM(
8660 "glGetVertexAttribPointerv", pname, "pname");
[email protected]f7a64ee2010-02-01 22:24:148661 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368662 }
[email protected]3916c97e2010-02-25 03:20:508663 if (index >= group_->max_vertex_attribs()) {
[email protected]ab09b612013-03-11 22:11:518664 LOCAL_SET_GL_ERROR(
8665 GL_INVALID_VALUE, "glGetVertexAttribPointerv", "index out of range.");
[email protected]f7a64ee2010-02-01 22:24:148666 return error::kNoError;
[email protected]8bf5a3e2010-01-29 04:21:368667 }
[email protected]0bfd9882010-02-05 23:02:258668 result->SetNumResults(1);
[email protected]f39f4b3f2010-05-12 17:04:088669 *result->GetData() =
[email protected]ed9f9cd2013-02-27 21:12:358670 state_.vertex_attrib_manager->GetVertexAttrib(index)->offset();
[email protected]f7a64ee2010-02-01 22:24:148671 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328672}
8673
[email protected]f7b85372010-02-03 01:11:378674bool GLES2DecoderImpl::GetUniformSetup(
[email protected]df37b9932013-03-08 05:21:428675 GLuint program_id, GLint fake_location,
[email protected]f7b85372010-02-03 01:11:378676 uint32 shm_id, uint32 shm_offset,
[email protected]1b0a6752012-02-22 03:44:128677 error::Error* error, GLint* real_location,
8678 GLuint* service_id, void** result_pointer, GLenum* result_type) {
[email protected]939e7362010-05-13 20:49:108679 DCHECK(error);
8680 DCHECK(service_id);
8681 DCHECK(result_pointer);
8682 DCHECK(result_type);
[email protected]1b0a6752012-02-22 03:44:128683 DCHECK(real_location);
[email protected]f7b85372010-02-03 01:11:378684 *error = error::kNoError;
8685 // Make sure we have enough room for the result on failure.
[email protected]0bfd9882010-02-05 23:02:258686 SizedResult<GLint>* result;
8687 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8688 shm_id, shm_offset, SizedResult<GLint>::ComputeSize(0));
8689 if (!result) {
[email protected]f7b85372010-02-03 01:11:378690 *error = error::kOutOfBounds;
8691 return false;
8692 }
[email protected]0bfd9882010-02-05 23:02:258693 *result_pointer = result;
[email protected]f7b85372010-02-03 01:11:378694 // Set the result size to 0 so the client does not have to check for success.
[email protected]0bfd9882010-02-05 23:02:258695 result->SetNumResults(0);
[email protected]df37b9932013-03-08 05:21:428696 Program* program = GetProgramInfoNotShader(program_id, "glGetUniform");
8697 if (!program) {
[email protected]ae51d192010-04-27 00:48:038698 return false;
8699 }
[email protected]df37b9932013-03-08 05:21:428700 if (!program->IsValid()) {
[email protected]f7b85372010-02-03 01:11:378701 // Program was not linked successfully. (ie, glLinkProgram)
[email protected]ab09b612013-03-11 22:11:518702 LOCAL_SET_GL_ERROR(
8703 GL_INVALID_OPERATION, "glGetUniform", "program not linked");
[email protected]f7b85372010-02-03 01:11:378704 return false;
8705 }
[email protected]df37b9932013-03-08 05:21:428706 *service_id = program->service_id();
[email protected]43c2f1f2011-03-25 18:35:368707 GLint array_index = -1;
[email protected]ed9f9cd2013-02-27 21:12:358708 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428709 program->GetUniformInfoByFakeLocation(
[email protected]1b0a6752012-02-22 03:44:128710 fake_location, real_location, &array_index);
[email protected]43c2f1f2011-03-25 18:35:368711 if (!uniform_info) {
[email protected]f7b85372010-02-03 01:11:378712 // No such location.
[email protected]ab09b612013-03-11 22:11:518713 LOCAL_SET_GL_ERROR(
8714 GL_INVALID_OPERATION, "glGetUniform", "unknown location");
[email protected]f7b85372010-02-03 01:11:378715 return false;
8716 }
[email protected]43c2f1f2011-03-25 18:35:368717 GLenum type = uniform_info->type;
[email protected]3916c97e2010-02-25 03:20:508718 GLsizei size = GLES2Util::GetGLDataTypeSizeForUniforms(type);
[email protected]f7b85372010-02-03 01:11:378719 if (size == 0) {
[email protected]ab09b612013-03-11 22:11:518720 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glGetUniform", "unknown type");
[email protected]f7b85372010-02-03 01:11:378721 return false;
8722 }
[email protected]0bfd9882010-02-05 23:02:258723 result = GetSharedMemoryAs<SizedResult<GLint>*>(
8724 shm_id, shm_offset, SizedResult<GLint>::ComputeSizeFromBytes(size));
8725 if (!result) {
[email protected]f7b85372010-02-03 01:11:378726 *error = error::kOutOfBounds;
8727 return false;
8728 }
[email protected]0bfd9882010-02-05 23:02:258729 result->size = size;
[email protected]939e7362010-05-13 20:49:108730 *result_type = type;
[email protected]f7b85372010-02-03 01:11:378731 return true;
8732}
8733
[email protected]f7a64ee2010-02-01 22:24:148734error::Error GLES2DecoderImpl::HandleGetUniformiv(
[email protected]ed9f9cd2013-02-27 21:12:358735 uint32 immediate_data_size, const cmds::GetUniformiv& c) {
[email protected]f7b85372010-02-03 01:11:378736 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338737 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378738 GLuint service_id;
[email protected]939e7362010-05-13 20:49:108739 GLenum result_type;
[email protected]1b0a6752012-02-22 03:44:128740 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378741 Error error;
[email protected]0bfd9882010-02-05 23:02:258742 void* result;
[email protected]f7b85372010-02-03 01:11:378743 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128744 program, fake_location, c.params_shm_id, c.params_shm_offset,
8745 &error, &real_location, &service_id, &result, &result_type)) {
[email protected]0bfd9882010-02-05 23:02:258746 glGetUniformiv(
[email protected]1b0a6752012-02-22 03:44:128747 service_id, real_location,
[email protected]ed9f9cd2013-02-27 21:12:358748 static_cast<cmds::GetUniformiv::Result*>(result)->GetData());
[email protected]f7b85372010-02-03 01:11:378749 }
8750 return error;
[email protected]96449d2c2009-11-25 00:01:328751}
8752
[email protected]f7a64ee2010-02-01 22:24:148753error::Error GLES2DecoderImpl::HandleGetUniformfv(
[email protected]ed9f9cd2013-02-27 21:12:358754 uint32 immediate_data_size, const cmds::GetUniformfv& c) {
[email protected]f7b85372010-02-03 01:11:378755 GLuint program = c.program;
[email protected]2be6abf32012-06-26 00:28:338756 GLint fake_location = c.location;
[email protected]f7b85372010-02-03 01:11:378757 GLuint service_id;
[email protected]1b0a6752012-02-22 03:44:128758 GLint real_location = -1;
[email protected]f7b85372010-02-03 01:11:378759 Error error;
[email protected]ed9f9cd2013-02-27 21:12:358760 typedef cmds::GetUniformfv::Result Result;
[email protected]939e7362010-05-13 20:49:108761 Result* result;
8762 GLenum result_type;
[email protected]f7b85372010-02-03 01:11:378763 if (GetUniformSetup(
[email protected]1b0a6752012-02-22 03:44:128764 program, fake_location, c.params_shm_id, c.params_shm_offset,
8765 &error, &real_location, &service_id,
8766 reinterpret_cast<void**>(&result), &result_type)) {
[email protected]939e7362010-05-13 20:49:108767 if (result_type == GL_BOOL || result_type == GL_BOOL_VEC2 ||
8768 result_type == GL_BOOL_VEC3 || result_type == GL_BOOL_VEC4) {
8769 GLsizei num_values = result->GetNumResults();
[email protected]40d90a22013-04-09 03:39:558770 scoped_ptr<GLint[]> temp(new GLint[num_values]);
[email protected]1b0a6752012-02-22 03:44:128771 glGetUniformiv(service_id, real_location, temp.get());
[email protected]939e7362010-05-13 20:49:108772 GLfloat* dst = result->GetData();
8773 for (GLsizei ii = 0; ii < num_values; ++ii) {
8774 dst[ii] = (temp[ii] != 0);
8775 }
8776 } else {
[email protected]1b0a6752012-02-22 03:44:128777 glGetUniformfv(service_id, real_location, result->GetData());
[email protected]939e7362010-05-13 20:49:108778 }
[email protected]f7b85372010-02-03 01:11:378779 }
8780 return error;
[email protected]96449d2c2009-11-25 00:01:328781}
8782
[email protected]f7a64ee2010-02-01 22:24:148783error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
[email protected]ed9f9cd2013-02-27 21:12:358784 uint32 immediate_data_size, const cmds::GetShaderPrecisionFormat& c) {
[email protected]0bfd9882010-02-05 23:02:258785 GLenum shader_type = static_cast<GLenum>(c.shadertype);
8786 GLenum precision_type = static_cast<GLenum>(c.precisiontype);
[email protected]ed9f9cd2013-02-27 21:12:358787 typedef cmds::GetShaderPrecisionFormat::Result Result;
[email protected]0bfd9882010-02-05 23:02:258788 Result* result = GetSharedMemoryAs<Result*>(
8789 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8790 if (!result) {
8791 return error::kOutOfBounds;
8792 }
[email protected]07d0cc82010-02-17 04:51:408793 // Check that the client initialized the result.
8794 if (result->success != 0) {
8795 return error::kInvalidArguments;
8796 }
[email protected]9438b012010-06-15 22:55:058797 if (!validators_->shader_type.IsValid(shader_type)) {
[email protected]ab09b612013-03-11 22:11:518798 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538799 "glGetShaderPrecisionFormat", shader_type, "shader_type");
[email protected]8eee29c2010-04-29 03:38:298800 return error::kNoError;
8801 }
[email protected]9438b012010-06-15 22:55:058802 if (!validators_->shader_precision.IsValid(precision_type)) {
[email protected]ab09b612013-03-11 22:11:518803 LOCAL_SET_GL_ERROR_INVALID_ENUM(
[email protected]f80e6e12012-08-31 00:43:538804 "glGetShaderPrecisionFormat", precision_type, "precision_type");
[email protected]8eee29c2010-04-29 03:38:298805 return error::kNoError;
8806 }
8807
8808 result->success = 1; // true
[email protected]d8bc3ec2013-03-07 06:28:408809
[email protected]46c86752013-05-21 05:08:398810 GLint range[2] = { 0, 0 };
[email protected]d8bc3ec2013-03-07 06:28:408811 GLint precision = 0;
[email protected]8dc1bf92013-03-12 03:58:218812 GetShaderPrecisionFormatImpl(shader_type, precision_type, range, &precision);
[email protected]d8bc3ec2013-03-07 06:28:408813
8814 result->min_range = range[0];
8815 result->max_range = range[1];
8816 result->precision = precision;
8817
[email protected]f7a64ee2010-02-01 22:24:148818 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328819}
8820
[email protected]f7a64ee2010-02-01 22:24:148821error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
[email protected]ed9f9cd2013-02-27 21:12:358822 uint32 immediate_data_size, const cmds::GetAttachedShaders& c) {
[email protected]0bfd9882010-02-05 23:02:258823 uint32 result_size = c.result_size;
[email protected]df37b9932013-03-08 05:21:428824 GLuint program_id = static_cast<GLuint>(c.program);
8825 Program* program = GetProgramInfoNotShader(
8826 program_id, "glGetAttachedShaders");
8827 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258828 return error::kNoError;
8829 }
[email protected]ed9f9cd2013-02-27 21:12:358830 typedef cmds::GetAttachedShaders::Result Result;
[email protected]0bfd9882010-02-05 23:02:258831 uint32 max_count = Result::ComputeMaxResults(result_size);
8832 Result* result = GetSharedMemoryAs<Result*>(
8833 c.result_shm_id, c.result_shm_offset, Result::ComputeSize(max_count));
8834 if (!result) {
8835 return error::kOutOfBounds;
8836 }
[email protected]07d0cc82010-02-17 04:51:408837 // Check that the client initialized the result.
8838 if (result->size != 0) {
8839 return error::kInvalidArguments;
8840 }
[email protected]0bfd9882010-02-05 23:02:258841 GLsizei count = 0;
[email protected]ae51d192010-04-27 00:48:038842 glGetAttachedShaders(
[email protected]df37b9932013-03-08 05:21:428843 program->service_id(), max_count, &count, result->GetData());
[email protected]0bfd9882010-02-05 23:02:258844 for (GLsizei ii = 0; ii < count; ++ii) {
[email protected]ae51d192010-04-27 00:48:038845 if (!shader_manager()->GetClientId(result->GetData()[ii],
8846 &result->GetData()[ii])) {
[email protected]0bfd9882010-02-05 23:02:258847 NOTREACHED();
8848 return error::kGenericError;
8849 }
8850 }
8851 result->SetNumResults(count);
[email protected]f7a64ee2010-02-01 22:24:148852 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328853}
8854
[email protected]f7a64ee2010-02-01 22:24:148855error::Error GLES2DecoderImpl::HandleGetActiveUniform(
[email protected]ed9f9cd2013-02-27 21:12:358856 uint32 immediate_data_size, const cmds::GetActiveUniform& c) {
[email protected]df37b9932013-03-08 05:21:428857 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258858 GLuint index = c.index;
8859 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358860 typedef cmds::GetActiveUniform::Result Result;
[email protected]0bfd9882010-02-05 23:02:258861 Result* result = GetSharedMemoryAs<Result*>(
8862 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8863 if (!result) {
8864 return error::kOutOfBounds;
8865 }
[email protected]07d0cc82010-02-17 04:51:408866 // Check that the client initialized the result.
8867 if (result->success != 0) {
8868 return error::kInvalidArguments;
8869 }
[email protected]df37b9932013-03-08 05:21:428870 Program* program = GetProgramInfoNotShader(
8871 program_id, "glGetActiveUniform");
8872 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258873 return error::kNoError;
8874 }
[email protected]ed9f9cd2013-02-27 21:12:358875 const Program::UniformInfo* uniform_info =
[email protected]df37b9932013-03-08 05:21:428876 program->GetUniformInfo(index);
[email protected]0bfd9882010-02-05 23:02:258877 if (!uniform_info) {
[email protected]ab09b612013-03-11 22:11:518878 LOCAL_SET_GL_ERROR(
8879 GL_INVALID_VALUE, "glGetActiveUniform", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258880 return error::kNoError;
8881 }
8882 result->success = 1; // true.
8883 result->size = uniform_info->size;
8884 result->type = uniform_info->type;
8885 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298886 bucket->SetFromString(uniform_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148887 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328888}
8889
[email protected]f7a64ee2010-02-01 22:24:148890error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
[email protected]ed9f9cd2013-02-27 21:12:358891 uint32 immediate_data_size, const cmds::GetActiveAttrib& c) {
[email protected]df37b9932013-03-08 05:21:428892 GLuint program_id = c.program;
[email protected]0bfd9882010-02-05 23:02:258893 GLuint index = c.index;
8894 uint32 name_bucket_id = c.name_bucket_id;
[email protected]ed9f9cd2013-02-27 21:12:358895 typedef cmds::GetActiveAttrib::Result Result;
[email protected]0bfd9882010-02-05 23:02:258896 Result* result = GetSharedMemoryAs<Result*>(
8897 c.result_shm_id, c.result_shm_offset, sizeof(*result));
8898 if (!result) {
8899 return error::kOutOfBounds;
8900 }
[email protected]07d0cc82010-02-17 04:51:408901 // Check that the client initialized the result.
8902 if (result->success != 0) {
8903 return error::kInvalidArguments;
8904 }
[email protected]df37b9932013-03-08 05:21:428905 Program* program = GetProgramInfoNotShader(
8906 program_id, "glGetActiveAttrib");
8907 if (!program) {
[email protected]0bfd9882010-02-05 23:02:258908 return error::kNoError;
8909 }
[email protected]ed9f9cd2013-02-27 21:12:358910 const Program::VertexAttrib* attrib_info =
[email protected]df37b9932013-03-08 05:21:428911 program->GetAttribInfo(index);
[email protected]0bfd9882010-02-05 23:02:258912 if (!attrib_info) {
[email protected]ab09b612013-03-11 22:11:518913 LOCAL_SET_GL_ERROR(
8914 GL_INVALID_VALUE, "glGetActiveAttrib", "index out of range");
[email protected]0bfd9882010-02-05 23:02:258915 return error::kNoError;
8916 }
8917 result->success = 1; // true.
8918 result->size = attrib_info->size;
8919 result->type = attrib_info->type;
8920 Bucket* bucket = CreateBucket(name_bucket_id);
[email protected]262d7aa2010-12-03 22:07:298921 bucket->SetFromString(attrib_info->name.c_str());
[email protected]f7a64ee2010-02-01 22:24:148922 return error::kNoError;
[email protected]96449d2c2009-11-25 00:01:328923}
8924
[email protected]b273e432010-04-12 17:23:588925error::Error GLES2DecoderImpl::HandleShaderBinary(
[email protected]ed9f9cd2013-02-27 21:12:358926 uint32 immediate_data_size, const cmds::ShaderBinary& c) {
[email protected]b273e432010-04-12 17:23:588927#if 1 // No binary shader support.
[email protected]ab09b612013-03-11 22:11:518928 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
[email protected]b273e432010-04-12 17:23:588929 return error::kNoError;
8930#else
8931 GLsizei n = static_cast<GLsizei>(c.n);
8932 if (n < 0) {
[email protected]ab09b612013-03-11 22:11:518933 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "n < 0");
[email protected]b273e432010-04-12 17:23:588934 return error::kNoError;
8935 }
8936 GLsizei length = static_cast<GLsizei>(c.length);
8937 if (length < 0) {
[email protected]ab09b612013-03-11 22:11:518938 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "length < 0");
[email protected]b273e432010-04-12 17:23:588939 return error::kNoError;
8940 }
8941 uint32 data_size;
8942 if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
8943 return error::kOutOfBounds;
8944 }
8945 const GLuint* shaders = GetSharedMemoryAs<const GLuint*>(
8946 c.shaders_shm_id, c.shaders_shm_offset, data_size);
8947 GLenum binaryformat = static_cast<GLenum>(c.binaryformat);
8948 const void* binary = GetSharedMemoryAs<const void*>(
8949 c.binary_shm_id, c.binary_shm_offset, length);
8950 if (shaders == NULL || binary == NULL) {
8951 return error::kOutOfBounds;
8952 }
8953 scoped_array<GLuint> service_ids(new GLuint[n]);
8954 for (GLsizei ii = 0; ii < n; ++ii) {
[email protected]df37b9932013-03-08 05:21:428955 Shader* shader = GetShader(shaders[ii]);
8956 if (!shader) {
[email protected]ab09b612013-03-11 22:11:518957 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glShaderBinary", "unknown shader");
[email protected]b273e432010-04-12 17:23:588958 return error::kNoError;
8959 }
[email protected]df37b9932013-03-08 05:21:428960 service_ids[ii] = shader->service_id();
[email protected]b273e432010-04-12 17:23:588961 }
8962 // TODO(gman): call glShaderBinary
8963 return error::kNoError;
8964#endif
8965}
8966
[email protected]6d792ee12013-05-15 00:40:568967void GLES2DecoderImpl::DoSwapBuffers() {
[email protected]64ace852011-05-19 21:49:498968 bool is_offscreen = !!offscreen_target_frame_buffer_.get();
[email protected]a7266a92012-06-28 02:11:088969
[email protected]64ace852011-05-19 21:49:498970 int this_frame_number = frame_number_++;
[email protected]2ac620e52012-07-23 20:31:428971 // TRACE_EVENT for gpu tests:
8972 TRACE_EVENT_INSTANT2("test_gpu", "SwapBuffersLatency",
[email protected]c76faea2013-03-26 07:42:428973 TRACE_EVENT_SCOPE_THREAD,
[email protected]2ac620e52012-07-23 20:31:428974 "GLImpl", static_cast<int>(gfx::GetGLImplementation()),
8975 "width", (is_offscreen ? offscreen_size_.width() :
8976 surface_->GetSize().width()));
[email protected]6d792ee12013-05-15 00:40:568977 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoSwapBuffers",
[email protected]64ace852011-05-19 21:49:498978 "offscreen", is_offscreen,
8979 "frame", this_frame_number);
[email protected]b2e92592014-01-10 15:47:158980 {
8981 TRACE_EVENT_SYNTHETIC_DELAY("gpu.SwapBuffers");
8982 }
8983
[email protected]8f9b8dd2013-09-12 18:05:138984 bool is_tracing;
8985 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("gpu.debug"),
8986 &is_tracing);
8987 if (is_tracing) {
8988 ScopedFrameBufferBinder binder(this, GetBackbufferServiceId());
8989 gpu_state_tracer_->TakeSnapshotWithCurrentFramebuffer(
8990 is_offscreen ? offscreen_size_ : surface_->GetSize());
8991 }
8992
[email protected]6217d392010-03-25 22:08:358993 // If offscreen then don't actually SwapBuffers to the display. Just copy
8994 // the rendered frame to another frame buffer.
[email protected]64ace852011-05-19 21:49:498995 if (is_offscreen) {
[email protected]111975c62012-09-06 01:37:318996 TRACE_EVENT2("gpu", "Offscreen",
8997 "width", offscreen_size_.width(), "height", offscreen_size_.height());
[email protected]1fb8c482011-08-31 01:01:538998 if (offscreen_size_ != offscreen_saved_color_texture_->size()) {
8999 // Workaround for NVIDIA driver bug on OS X; crbug.com/89557,
9000 // crbug.com/94163. TODO(kbr): figure out reproduction so Apple will
9001 // fix this.
[email protected]62e155e2012-10-23 22:43:159002 if (workarounds().needs_offscreen_buffer_workaround) {
[email protected]1fb8c482011-08-31 01:01:539003 offscreen_saved_frame_buffer_->Create();
9004 glFinish();
9005 }
9006
9007 // Allocate the offscreen saved color texture.
9008 DCHECK(offscreen_saved_color_format_);
9009 offscreen_saved_color_texture_->AllocateStorage(
[email protected]678a73f2012-12-19 19:22:099010 offscreen_size_, offscreen_saved_color_format_, false);
[email protected]1fb8c482011-08-31 01:01:539011
9012 offscreen_saved_frame_buffer_->AttachRenderTexture(
9013 offscreen_saved_color_texture_.get());
[email protected]f0cfe752013-01-14 01:09:059014 if (offscreen_size_.width() != 0 && offscreen_size_.height() != 0) {
9015 if (offscreen_saved_frame_buffer_->CheckStatus() !=
9016 GL_FRAMEBUFFER_COMPLETE) {
9017 LOG(ERROR) << "GLES2DecoderImpl::ResizeOffscreenFrameBuffer failed "
9018 << "because offscreen saved FBO was incomplete.";
[email protected]6d792ee12013-05-15 00:40:569019 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
9020 return;
[email protected]f0cfe752013-01-14 01:09:059021 }
[email protected]1fb8c482011-08-31 01:01:539022
[email protected]f0cfe752013-01-14 01:09:059023 // Clear the offscreen color texture.
9024 // TODO(piman): Is this still necessary?
9025 {
9026 ScopedFrameBufferBinder binder(this,
9027 offscreen_saved_frame_buffer_->id());
9028 glClearColor(0, 0, 0, 0);
9029 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
9030 glDisable(GL_SCISSOR_TEST);
9031 glClear(GL_COLOR_BUFFER_BIT);
9032 RestoreClearState();
9033 }
[email protected]1fb8c482011-08-31 01:01:539034 }
9035
9036 UpdateParentTextureInfo();
9037 }
9038
[email protected]f0cfe752013-01-14 01:09:059039 if (offscreen_size_.width() == 0 || offscreen_size_.height() == 0)
[email protected]6d792ee12013-05-15 00:40:569040 return;
[email protected]ab09b612013-03-11 22:11:519041 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:309042 "GLES2DecoderImpl::DoSwapBuffers", GetErrorState());
[email protected]6217d392010-03-25 22:08:359043
[email protected]34ff8b0c2010-10-01 20:06:029044 if (IsOffscreenBufferMultisampled()) {
[email protected]51411e32012-01-19 20:21:139045 // For multisampled buffers, resolve the frame buffer.
[email protected]de26b3c2011-08-03 21:54:279046 ScopedResolvedFrameBufferBinder binder(this, true, false);
[email protected]b86b14982010-10-11 18:45:489047 } else {
[email protected]069944672012-04-25 20:52:239048 ScopedFrameBufferBinder binder(this,
9049 offscreen_target_frame_buffer_->id());
[email protected]51411e32012-01-19 20:21:139050
[email protected]069944672012-04-25 20:52:239051 if (offscreen_target_buffer_preserved_) {
9052 // Copy the target frame buffer to the saved offscreen texture.
9053 offscreen_saved_color_texture_->Copy(
9054 offscreen_saved_color_texture_->size(),
9055 offscreen_saved_color_format_);
9056 } else {
9057 // Flip the textures in the parent context via the texture manager.
9058 if (!!offscreen_saved_color_texture_info_.get())
[email protected]370eaf12013-05-18 09:19:499059 offscreen_saved_color_texture_info_->texture()->
[email protected]069944672012-04-25 20:52:239060 SetServiceId(offscreen_target_color_texture_->id());
[email protected]8a61d872012-01-20 12:43:569061
[email protected]069944672012-04-25 20:52:239062 offscreen_saved_color_texture_.swap(offscreen_target_color_texture_);
9063 offscreen_target_frame_buffer_->AttachRenderTexture(
9064 offscreen_target_color_texture_.get());
[email protected]b86b14982010-10-11 18:45:489065 }
[email protected]069944672012-04-25 20:52:239066
9067 // Ensure the side effects of the copy are visible to the parent
9068 // context. There is no need to do this for ANGLE because it uses a
9069 // single D3D device for all contexts.
[email protected]f42f05b2013-11-15 21:46:189070 if (!feature_info_->feature_flags().is_angle)
[email protected]069944672012-04-25 20:52:239071 glFlush();
[email protected]0c8c9d22010-06-25 17:36:399072 }
[email protected]6217d392010-03-25 22:08:359073 } else {
[email protected]111975c62012-09-06 01:37:319074 TRACE_EVENT2("gpu", "Onscreen",
9075 "width", surface_->GetSize().width(),
9076 "height", surface_->GetSize().height());
[email protected]f62a5ab2011-05-23 20:34:159077 if (!surface_->SwapBuffers()) {
[email protected]d0498742010-09-20 20:27:019078 LOG(ERROR) << "Context lost because SwapBuffers failed.";
[email protected]6d792ee12013-05-15 00:40:569079 LoseContext(GL_UNKNOWN_CONTEXT_RESET_ARB);
[email protected]d0498742010-09-20 20:27:019080 }
[email protected]6217d392010-03-25 22:08:359081 }
[email protected]6217d392010-03-25 22:08:359082}
9083
[email protected]d4239852011-08-12 04:51:229084error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359085 uint32 immediate_data_size, const cmds::EnableFeatureCHROMIUM& c) {
[email protected]b1d2dcb2010-05-17 19:24:189086 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289087 if (!bucket || bucket->size() == 0) {
9088 return error::kInvalidArguments;
9089 }
[email protected]ed9f9cd2013-02-27 21:12:359090 typedef cmds::EnableFeatureCHROMIUM::Result Result;
[email protected]b1d2dcb2010-05-17 19:24:189091 Result* result = GetSharedMemoryAs<Result*>(
9092 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9093 if (!result) {
9094 return error::kOutOfBounds;
[email protected]4e8a5b122010-05-08 22:00:109095 }
[email protected]b1d2dcb2010-05-17 19:24:189096 // Check that the client initialized the result.
9097 if (*result != 0) {
9098 return error::kInvalidArguments;
9099 }
9100 std::string feature_str;
9101 if (!bucket->GetAsString(&feature_str)) {
9102 return error::kInvalidArguments;
9103 }
9104
9105 // TODO(gman): make this some kind of table to function pointer thingy.
[email protected]d4239852011-08-12 04:51:229106 if (feature_str.compare("pepper3d_allow_buffers_on_multiple_targets") == 0) {
[email protected]b1d2dcb2010-05-17 19:24:189107 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
[email protected]d4239852011-08-12 04:51:229108 } else if (feature_str.compare("pepper3d_support_fixed_attribs") == 0) {
[email protected]8fbedc02010-11-18 18:43:409109 buffer_manager()->set_allow_buffers_on_multiple_targets(true);
9110 // TODO(gman): decide how to remove the need for this const_cast.
9111 // I could make validators_ non const but that seems bad as this is the only
9112 // place it is needed. I could make some special friend class of validators
9113 // just to allow this to set them. That seems silly. I could refactor this
9114 // code to use the extension mechanism or the initialization attributes to
9115 // turn this feature on. Given that the only real point of this is to make
9116 // the conformance tests pass and given that there is lots of real work that
9117 // needs to be done it seems like refactoring for one to one of those
9118 // methods is a very low priority.
9119 const_cast<Validators*>(validators_)->vertex_attrib_type.AddValue(GL_FIXED);
[email protected]f0d74742011-10-03 16:31:049120 } else if (feature_str.compare("webgl_enable_glsl_webgl_validation") == 0) {
9121 force_webgl_glsl_validation_ = true;
9122 InitializeShaderTranslator();
[email protected]b1d2dcb2010-05-17 19:24:189123 } else {
9124 return error::kNoError;
9125 }
9126
9127 *result = 1; // true.
9128 return error::kNoError;
[email protected]4e8a5b122010-05-08 22:00:109129}
9130
[email protected]c2f8c8402010-12-06 18:07:249131error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
9132 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359133 const cmds::GetRequestableExtensionsCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:249134 Bucket* bucket = CreateBucket(c.bucket_id);
[email protected]ed9f9cd2013-02-27 21:12:359135 scoped_refptr<FeatureInfo> info(new FeatureInfo());
[email protected]956aec52013-09-05 15:41:199136 info->Initialize(disallowed_features_);
[email protected]c2f8c8402010-12-06 18:07:249137 bucket->SetFromString(info->extensions().c_str());
9138 return error::kNoError;
9139}
9140
9141error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359142 uint32 immediate_data_size, const cmds::RequestExtensionCHROMIUM& c) {
[email protected]c2f8c8402010-12-06 18:07:249143 Bucket* bucket = GetBucket(c.bucket_id);
[email protected]12f93d82011-10-17 21:16:289144 if (!bucket || bucket->size() == 0) {
9145 return error::kInvalidArguments;
9146 }
[email protected]c2f8c8402010-12-06 18:07:249147 std::string feature_str;
9148 if (!bucket->GetAsString(&feature_str)) {
9149 return error::kInvalidArguments;
9150 }
9151
[email protected]4b7eba92013-01-08 02:23:569152 bool desire_webgl_glsl_validation =
9153 feature_str.find("GL_CHROMIUM_webglsl") != std::string::npos;
9154 bool desire_standard_derivatives = false;
[email protected]70dc60932013-06-04 03:33:499155 bool desire_frag_depth = false;
[email protected]aff39ac82013-06-08 04:53:139156 bool desire_draw_buffers = false;
[email protected]4b7eba92013-01-08 02:23:569157 if (force_webgl_glsl_validation_) {
9158 desire_standard_derivatives =
9159 feature_str.find("GL_OES_standard_derivatives") != std::string::npos;
[email protected]70dc60932013-06-04 03:33:499160 desire_frag_depth =
9161 feature_str.find("GL_EXT_frag_depth") != std::string::npos;
[email protected]aff39ac82013-06-08 04:53:139162 desire_draw_buffers =
9163 feature_str.find("GL_EXT_draw_buffers") != std::string::npos;
[email protected]f0d74742011-10-03 16:31:049164 }
9165
[email protected]4b7eba92013-01-08 02:23:569166 if (desire_webgl_glsl_validation != force_webgl_glsl_validation_ ||
[email protected]70dc60932013-06-04 03:33:499167 desire_standard_derivatives != derivatives_explicitly_enabled_ ||
[email protected]aff39ac82013-06-08 04:53:139168 desire_frag_depth != frag_depth_explicitly_enabled_ ||
9169 desire_draw_buffers != draw_buffers_explicitly_enabled_) {
[email protected]70dc60932013-06-04 03:33:499170 force_webgl_glsl_validation_ |= desire_webgl_glsl_validation;
9171 derivatives_explicitly_enabled_ |= desire_standard_derivatives;
9172 frag_depth_explicitly_enabled_ |= desire_frag_depth;
[email protected]aff39ac82013-06-08 04:53:139173 draw_buffers_explicitly_enabled_ |= desire_draw_buffers;
[email protected]c2f8c8402010-12-06 18:07:249174 InitializeShaderTranslator();
9175 }
9176
[email protected]302ce6d2011-07-07 23:28:119177 UpdateCapabilities();
9178
[email protected]c2f8c8402010-12-06 18:07:249179 return error::kNoError;
9180}
9181
[email protected]372e0412011-06-28 16:08:569182error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359183 uint32 immediate_data_size, const cmds::GetMultipleIntegervCHROMIUM& c) {
[email protected]372e0412011-06-28 16:08:569184 GLuint count = c.count;
9185 uint32 pnames_size;
9186 if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
9187 return error::kOutOfBounds;
9188 }
9189 const GLenum* pnames = GetSharedMemoryAs<const GLenum*>(
9190 c.pnames_shm_id, c.pnames_shm_offset, pnames_size);
9191 if (pnames == NULL) {
9192 return error::kOutOfBounds;
9193 }
9194
9195 // We have to copy them since we use them twice so the client
9196 // can't change them between the time we validate them and the time we use
9197 // them.
[email protected]40d90a22013-04-09 03:39:559198 scoped_ptr<GLenum[]> enums(new GLenum[count]);
[email protected]372e0412011-06-28 16:08:569199 memcpy(enums.get(), pnames, pnames_size);
9200
9201 // Count up the space needed for the result.
9202 uint32 num_results = 0;
9203 for (GLuint ii = 0; ii < count; ++ii) {
9204 uint32 num = util_.GLGetNumValuesReturned(enums[ii]);
9205 if (num == 0) {
[email protected]ab09b612013-03-11 22:11:519206 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9207 "glGetMulitpleCHROMIUM", enums[ii], "pname");
[email protected]372e0412011-06-28 16:08:569208 return error::kNoError;
9209 }
9210 // Num will never be more than 4.
9211 DCHECK_LE(num, 4u);
[email protected]3aad1a32012-09-07 20:54:479212 if (!SafeAddUint32(num_results, num, &num_results)) {
[email protected]372e0412011-06-28 16:08:569213 return error::kOutOfBounds;
9214 }
9215 }
9216
9217 uint32 result_size = 0;
9218 if (!SafeMultiplyUint32(num_results, sizeof(GLint), &result_size)) {
9219 return error::kOutOfBounds;
9220 }
9221
9222 if (result_size != static_cast<uint32>(c.size)) {
[email protected]ab09b612013-03-11 22:11:519223 LOCAL_SET_GL_ERROR(
9224 GL_INVALID_VALUE,
9225 "glGetMulitpleCHROMIUM", "bad size GL_INVALID_VALUE");
[email protected]372e0412011-06-28 16:08:569226 return error::kNoError;
9227 }
9228
9229 GLint* results = GetSharedMemoryAs<GLint*>(
9230 c.results_shm_id, c.results_shm_offset, result_size);
9231 if (results == NULL) {
9232 return error::kOutOfBounds;
9233 }
9234
9235 // Check the results have been cleared in case the context was lost.
9236 for (uint32 ii = 0; ii < num_results; ++ii) {
9237 if (results[ii]) {
9238 return error::kInvalidArguments;
9239 }
9240 }
9241
9242 // Get each result.
9243 GLint* start = results;
9244 for (GLuint ii = 0; ii < count; ++ii) {
9245 GLsizei num_written = 0;
[email protected]d058bca2012-11-26 10:27:269246 if (!state_.GetStateAsGLint(enums[ii], results, &num_written) &&
[email protected]f63b1232012-10-31 07:03:539247 !GetHelper(enums[ii], results, &num_written)) {
[email protected]b0ce0982013-05-13 18:51:489248 DoGetIntegerv(enums[ii], results);
[email protected]372e0412011-06-28 16:08:569249 }
9250 results += num_written;
9251 }
9252
9253 // Just to verify. Should this be a DCHECK?
9254 if (static_cast<uint32>(results - start) != num_results) {
9255 return error::kOutOfBounds;
9256 }
9257
9258 return error::kNoError;
9259}
9260
[email protected]2318d342011-07-11 22:27:429261error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359262 uint32 immediate_data_size, const cmds::GetProgramInfoCHROMIUM& c) {
[email protected]df37b9932013-03-08 05:21:429263 GLuint program_id = static_cast<GLuint>(c.program);
[email protected]2318d342011-07-11 22:27:429264 uint32 bucket_id = c.bucket_id;
9265 Bucket* bucket = CreateBucket(bucket_id);
9266 bucket->SetSize(sizeof(ProgramInfoHeader)); // in case we fail.
[email protected]df37b9932013-03-08 05:21:429267 Program* program = NULL;
9268 program = GetProgram(program_id);
9269 if (!program || !program->IsValid()) {
[email protected]9a14ae612011-08-08 17:51:469270 return error::kNoError;
[email protected]2318d342011-07-11 22:27:429271 }
[email protected]df37b9932013-03-08 05:21:429272 program->GetProgramInfo(program_manager(), bucket);
[email protected]2318d342011-07-11 22:27:429273 return error::kNoError;
9274}
9275
[email protected]38d139d2011-07-14 00:38:439276error::ContextLostReason GLES2DecoderImpl::GetContextLostReason() {
9277 switch (reset_status_) {
[email protected]ad84a3a2012-06-08 21:42:439278 case GL_NO_ERROR:
9279 // TODO(kbr): improve the precision of the error code in this case.
9280 // Consider delegating to context for error code if MakeCurrent fails.
9281 return error::kUnknown;
9282 case GL_GUILTY_CONTEXT_RESET_ARB:
9283 return error::kGuilty;
9284 case GL_INNOCENT_CONTEXT_RESET_ARB:
9285 return error::kInnocent;
9286 case GL_UNKNOWN_CONTEXT_RESET_ARB:
9287 return error::kUnknown;
[email protected]38d139d2011-07-14 00:38:439288 }
9289
9290 NOTREACHED();
9291 return error::kUnknown;
9292}
9293
9294bool GLES2DecoderImpl::WasContextLost() {
[email protected]c4485aad62012-12-17 10:19:099295 if (reset_status_ != GL_NO_ERROR) {
9296 return true;
9297 }
[email protected]706b69f2012-07-27 04:59:309298 if (context_->WasAllocatedUsingRobustnessExtension()) {
9299 GLenum status = GL_NO_ERROR;
9300 if (has_robustness_extension_)
9301 status = glGetGraphicsResetStatusARB();
[email protected]38d139d2011-07-14 00:38:439302 if (status != GL_NO_ERROR) {
9303 // The graphics card was reset. Signal a lost context to the application.
9304 reset_status_ = status;
[email protected]93a7d98f2013-07-11 00:04:229305 reset_by_robustness_extension_ = true;
[email protected]38d139d2011-07-14 00:38:439306 LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
[email protected]c4485aad62012-12-17 10:19:099307 << " context lost via ARB/EXT_robustness. Reset status = "
9308 << GLES2Util::GetStringEnum(status);
[email protected]38d139d2011-07-14 00:38:439309 return true;
9310 }
9311 }
9312 return false;
9313}
9314
[email protected]93a7d98f2013-07-11 00:04:229315bool GLES2DecoderImpl::WasContextLostByRobustnessExtension() {
9316 return WasContextLost() && reset_by_robustness_extension_;
9317}
9318
[email protected]c4485aad62012-12-17 10:19:099319void GLES2DecoderImpl::LoseContext(uint32 reset_status) {
9320 // Only loses the context once.
9321 if (reset_status_ != GL_NO_ERROR) {
9322 return;
9323 }
9324
9325 // Marks this context as lost.
9326 reset_status_ = reset_status;
9327 current_decoder_error_ = error::kLostContext;
[email protected]c4485aad62012-12-17 10:19:099328}
9329
9330error::Error GLES2DecoderImpl::HandleLoseContextCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359331 uint32 immediate_data_size, const cmds::LoseContextCHROMIUM& c) {
[email protected]c4485aad62012-12-17 10:19:099332 GLenum current = static_cast<GLenum>(c.current);
9333 GLenum other = static_cast<GLenum>(c.other);
9334 if (!validators_->reset_status.IsValid(current)) {
[email protected]ab09b612013-03-11 22:11:519335 LOCAL_SET_GL_ERROR_INVALID_ENUM(
9336 "glLoseContextCHROMIUM", current, "current");
[email protected]c4485aad62012-12-17 10:19:099337 }
9338 if (!validators_->reset_status.IsValid(other)) {
[email protected]ab09b612013-03-11 22:11:519339 LOCAL_SET_GL_ERROR_INVALID_ENUM("glLoseContextCHROMIUM", other, "other");
[email protected]c4485aad62012-12-17 10:19:099340 }
9341 group_->LoseContexts(other);
9342 reset_status_ = current;
9343 current_decoder_error_ = error::kLostContext;
9344 return error::kLostContext;
9345}
9346
[email protected]b096d032013-03-08 03:08:019347error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
9348 uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) {
9349 return error::kUnknownCommand;
9350}
9351
[email protected]840a7e462013-02-27 01:29:519352error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:359353 uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) {
[email protected]840a7e462013-02-27 01:29:519354 if (wait_sync_point_callback_.is_null())
9355 return error::kNoError;
9356
9357 return wait_sync_point_callback_.Run(c.sync_point) ?
9358 error::kNoError : error::kDeferCommandUntilLater;
9359}
9360
[email protected]5dfc457b2013-12-13 11:13:079361error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
9362 uint32 immediate_data_size, const cmds::DiscardBackbufferCHROMIUM& c) {
9363 if (surface_->DeferDraws())
9364 return error::kDeferCommandUntilLater;
9365 if (!surface_->SetBackbufferAllocation(false))
9366 return error::kLostContext;
9367 backbuffer_needs_clear_bits_ |= GL_COLOR_BUFFER_BIT;
9368 backbuffer_needs_clear_bits_ |= GL_DEPTH_BUFFER_BIT;
9369 backbuffer_needs_clear_bits_ |= GL_STENCIL_BUFFER_BIT;
9370 return error::kNoError;
9371}
9372
[email protected]882ba1e22012-03-08 19:02:539373bool GLES2DecoderImpl::GenQueriesEXTHelper(
9374 GLsizei n, const GLuint* client_ids) {
9375 for (GLsizei ii = 0; ii < n; ++ii) {
9376 if (query_manager_->GetQuery(client_ids[ii])) {
9377 return false;
9378 }
9379 }
[email protected]c45f1972012-03-14 07:27:369380 // NOTE: We don't generate Query objects here. Only in BeginQueryEXT
[email protected]882ba1e22012-03-08 19:02:539381 return true;
9382}
9383
9384void GLES2DecoderImpl::DeleteQueriesEXTHelper(
9385 GLsizei n, const GLuint* client_ids) {
9386 for (GLsizei ii = 0; ii < n; ++ii) {
9387 QueryManager::Query* query = query_manager_->GetQuery(client_ids[ii]);
9388 if (query && !query->IsDeleted()) {
[email protected]8ebd46c2014-01-08 12:06:139389 ContextState::QueryMap::iterator it =
9390 state_.current_queries.find(query->target());
9391 if (it != state_.current_queries.end())
9392 state_.current_queries.erase(it);
9393
[email protected]c45f1972012-03-14 07:27:369394 query->Destroy(true);
[email protected]882ba1e22012-03-08 19:02:539395 query_manager_->RemoveQuery(client_ids[ii]);
9396 }
9397 }
9398}
9399
[email protected]22e3f552012-03-13 01:54:199400bool GLES2DecoderImpl::ProcessPendingQueries() {
9401 if (query_manager_.get() == NULL) {
9402 return false;
9403 }
[email protected]c45f1972012-03-14 07:27:369404 if (!query_manager_->ProcessPendingQueries()) {
[email protected]22e3f552012-03-13 01:54:199405 current_decoder_error_ = error::kOutOfBounds;
9406 }
9407 return query_manager_->HavePendingQueries();
9408}
9409
[email protected]5a36dc132013-07-23 23:17:559410// Note that if there are no pending readpixels right now,
9411// this function will call the callback immediately.
9412void GLES2DecoderImpl::WaitForReadPixels(base::Closure callback) {
9413 if (features().use_async_readpixels && !pending_readpixel_fences_.empty()) {
9414 pending_readpixel_fences_.back()->callbacks.push_back(callback);
9415 } else {
9416 callback.Run();
9417 }
9418}
9419
9420void GLES2DecoderImpl::ProcessPendingReadPixels() {
9421 while (!pending_readpixel_fences_.empty() &&
9422 pending_readpixel_fences_.front()->fence->HasCompleted()) {
9423 std::vector<base::Closure> callbacks =
9424 pending_readpixel_fences_.front()->callbacks;
9425 pending_readpixel_fences_.pop();
9426 for (size_t i = 0; i < callbacks.size(); i++) {
9427 callbacks[i].Run();
9428 }
9429 }
9430}
9431
[email protected]2b1767cf2013-03-16 09:25:059432bool GLES2DecoderImpl::HasMoreIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559433 return !pending_readpixel_fences_.empty() ||
9434 async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059435}
9436
9437void GLES2DecoderImpl::PerformIdleWork() {
[email protected]5a36dc132013-07-23 23:17:559438 ProcessPendingReadPixels();
[email protected]b68b100752013-06-05 08:34:489439 if (!async_pixel_transfer_manager_->NeedsProcessMorePendingTransfers())
[email protected]2b1767cf2013-03-16 09:25:059440 return;
[email protected]b68b100752013-06-05 08:34:489441 async_pixel_transfer_manager_->ProcessMorePendingTransfers();
[email protected]2b1767cf2013-03-16 09:25:059442 ProcessFinishedAsyncTransfers();
9443}
9444
[email protected]882ba1e22012-03-08 19:02:539445error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359446 uint32 immediate_data_size, const cmds::BeginQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539447 GLenum target = static_cast<GLenum>(c.target);
9448 GLuint client_id = static_cast<GLuint>(c.id);
9449 int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
9450 uint32 sync_shm_offset = static_cast<uint32>(c.sync_data_shm_offset);
9451
[email protected]c45f1972012-03-14 07:27:369452 switch (target) {
9453 case GL_COMMANDS_ISSUED_CHROMIUM:
[email protected]fb4bf5822012-10-23 21:25:559454 case GL_LATENCY_QUERY_CHROMIUM:
[email protected]5537605d2013-08-27 05:22:319455 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM:
9456 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
[email protected]620b0db02013-03-20 15:47:009457 case GL_GET_ERROR_QUERY_CHROMIUM:
[email protected]c45f1972012-03-14 07:27:369458 break;
9459 default:
[email protected]62e155e2012-10-23 22:43:159460 if (!features().occlusion_query_boolean) {
[email protected]ab09b612013-03-11 22:11:519461 LOCAL_SET_GL_ERROR(
[email protected]620b0db02013-03-20 15:47:009462 GL_INVALID_OPERATION, "glBeginQueryEXT",
9463 "not enabled for occlusion queries");
[email protected]c45f1972012-03-14 07:27:369464 return error::kNoError;
9465 }
9466 break;
[email protected]882ba1e22012-03-08 19:02:539467 }
9468
[email protected]8ebd46c2014-01-08 12:06:139469 if (state_.current_queries.find(target) != state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519470 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439471 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress");
[email protected]882ba1e22012-03-08 19:02:539472 return error::kNoError;
9473 }
9474
9475 if (client_id == 0) {
[email protected]ab09b612013-03-11 22:11:519476 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0");
[email protected]882ba1e22012-03-08 19:02:539477 return error::kNoError;
9478 }
9479
9480 QueryManager::Query* query = query_manager_->GetQuery(client_id);
9481 if (!query) {
[email protected]c45f1972012-03-14 07:27:369482 // TODO(gman): Decide if we need this check.
9483 //
[email protected]882ba1e22012-03-08 19:02:539484 // Checks id was made by glGenQueries
[email protected]c45f1972012-03-14 07:27:369485 //
9486 // From the POV of OpenGL ES 2.0 you need to call glGenQueriesEXT
9487 // for all Query ids but from the POV of the command buffer service maybe
9488 // you don't.
9489 //
9490 // The client can enforce this. I don't think the service cares.
9491 //
9492 // IdAllocatorInterface* id_allocator =
9493 // group_->GetIdAllocator(id_namespaces::kQueries);
9494 // if (!id_allocator->InUse(client_id)) {
[email protected]ab09b612013-03-11 22:11:519495 // LOCAL_SET_GL_ERROR(
9496 // GL_INVALID_OPERATION,
9497 // "glBeginQueryEXT", "id not made by glGenQueriesEXT");
[email protected]c45f1972012-03-14 07:27:369498 // return error::kNoError;
9499 // }
9500 query = query_manager_->CreateQuery(
9501 target, client_id, sync_shm_id, sync_shm_offset);
[email protected]882ba1e22012-03-08 19:02:539502 }
9503
[email protected]c45f1972012-03-14 07:27:369504 if (query->target() != target) {
[email protected]ab09b612013-03-11 22:11:519505 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439506 GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
[email protected]882ba1e22012-03-08 19:02:539507 return error::kNoError;
9508 } else if (query->shm_id() != sync_shm_id ||
9509 query->shm_offset() != sync_shm_offset) {
9510 DLOG(ERROR) << "Shared memory used by query not the same as before";
9511 return error::kInvalidArguments;
9512 }
9513
[email protected]c45f1972012-03-14 07:27:369514 if (!query_manager_->BeginQuery(query)) {
9515 return error::kOutOfBounds;
9516 }
[email protected]882ba1e22012-03-08 19:02:539517
[email protected]8ebd46c2014-01-08 12:06:139518 state_.current_queries[target] = query;
[email protected]882ba1e22012-03-08 19:02:539519 return error::kNoError;
9520}
9521
9522error::Error GLES2DecoderImpl::HandleEndQueryEXT(
[email protected]ed9f9cd2013-02-27 21:12:359523 uint32 immediate_data_size, const cmds::EndQueryEXT& c) {
[email protected]882ba1e22012-03-08 19:02:539524 GLenum target = static_cast<GLenum>(c.target);
9525 uint32 submit_count = static_cast<GLuint>(c.submit_count);
[email protected]8ebd46c2014-01-08 12:06:139526 ContextState::QueryMap::iterator it = state_.current_queries.find(target);
[email protected]882ba1e22012-03-08 19:02:539527
[email protected]8ebd46c2014-01-08 12:06:139528 if (it == state_.current_queries.end()) {
[email protected]ab09b612013-03-11 22:11:519529 LOCAL_SET_GL_ERROR(
9530 GL_INVALID_OPERATION, "glEndQueryEXT", "No active query");
[email protected]882ba1e22012-03-08 19:02:539531 return error::kNoError;
9532 }
[email protected]882ba1e22012-03-08 19:02:539533
[email protected]8ebd46c2014-01-08 12:06:139534 QueryManager::Query* query = it->second.get();
9535 if (!query_manager_->EndQuery(query, submit_count)) {
[email protected]c45f1972012-03-14 07:27:369536 return error::kOutOfBounds;
9537 }
9538
[email protected]fe8d73c2013-02-16 22:37:329539 query_manager_->ProcessPendingTransferQueries();
9540
[email protected]8ebd46c2014-01-08 12:06:139541 state_.current_queries.erase(it);
[email protected]882ba1e22012-03-08 19:02:539542 return error::kNoError;
9543}
9544
[email protected]944b62f32012-09-27 02:20:469545bool GLES2DecoderImpl::GenVertexArraysOESHelper(
9546 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469547 for (GLsizei ii = 0; ii < n; ++ii) {
9548 if (GetVertexAttribManager(client_ids[ii])) {
9549 return false;
9550 }
9551 }
[email protected]ab4fd7282012-10-12 16:25:579552
[email protected]62e155e2012-10-23 22:43:159553 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579554 // Emulated VAO
9555 for (GLsizei ii = 0; ii < n; ++ii) {
9556 CreateVertexAttribManager(client_ids[ii], 0);
9557 }
9558 } else {
[email protected]40d90a22013-04-09 03:39:559559 scoped_ptr<GLuint[]> service_ids(new GLuint[n]);
[email protected]ab4fd7282012-10-12 16:25:579560
9561 glGenVertexArraysOES(n, service_ids.get());
9562 for (GLsizei ii = 0; ii < n; ++ii) {
9563 CreateVertexAttribManager(client_ids[ii], service_ids[ii]);
9564 }
[email protected]944b62f32012-09-27 02:20:469565 }
[email protected]ab4fd7282012-10-12 16:25:579566
[email protected]944b62f32012-09-27 02:20:469567 return true;
9568}
9569
9570void GLES2DecoderImpl::DeleteVertexArraysOESHelper(
9571 GLsizei n, const GLuint* client_ids) {
[email protected]944b62f32012-09-27 02:20:469572 for (GLsizei ii = 0; ii < n; ++ii) {
9573 VertexAttribManager* vao =
9574 GetVertexAttribManager(client_ids[ii]);
9575 if (vao && !vao->IsDeleted()) {
[email protected]7cd76fd2013-06-02 21:11:119576 if (state_.vertex_attrib_manager.get() == vao) {
[email protected]e259eb412012-10-13 05:47:249577 state_.vertex_attrib_manager = default_vertex_attrib_manager_;
[email protected]944b62f32012-09-27 02:20:469578 }
9579 RemoveVertexAttribManager(client_ids[ii]);
9580 }
9581 }
9582}
9583
9584void GLES2DecoderImpl::DoBindVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469585 VertexAttribManager* vao = NULL;
9586 GLuint service_id = 0;
9587 if (client_id != 0) {
9588 vao = GetVertexAttribManager(client_id);
9589 if (!vao) {
9590 // Unlike most Bind* methods, the spec explicitly states that VertexArray
9591 // only allows names that have been previously generated. As such, we do
9592 // not generate new names here.
[email protected]ab09b612013-03-11 22:11:519593 LOCAL_SET_GL_ERROR(
9594 GL_INVALID_OPERATION,
9595 "glBindVertexArrayOES", "bad vertex array id.");
[email protected]944b62f32012-09-27 02:20:469596 current_decoder_error_ = error::kNoError;
9597 return;
9598 } else {
9599 service_id = vao->service_id();
9600 }
[email protected]944b62f32012-09-27 02:20:469601 } else {
[email protected]7cd76fd2013-06-02 21:11:119602 vao = default_vertex_attrib_manager_.get();
[email protected]944b62f32012-09-27 02:20:469603 }
9604
[email protected]ab4fd7282012-10-12 16:25:579605 // Only set the VAO state if it's changed
[email protected]7cd76fd2013-06-02 21:11:119606 if (state_.vertex_attrib_manager.get() != vao) {
[email protected]e259eb412012-10-13 05:47:249607 state_.vertex_attrib_manager = vao;
[email protected]62e155e2012-10-23 22:43:159608 if (!features().native_vertex_array_object) {
[email protected]ab4fd7282012-10-12 16:25:579609 EmulateVertexArrayState();
9610 } else {
9611 glBindVertexArrayOES(service_id);
9612 }
9613 }
9614}
9615
9616// Used when OES_vertex_array_object isn't natively supported
9617void GLES2DecoderImpl::EmulateVertexArrayState() {
9618 // Setup the Vertex attribute state
9619 for (uint32 vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
9620 RestoreStateForAttrib(vv);
9621 }
9622
9623 // Setup the element buffer
[email protected]16ccec12013-02-28 03:40:219624 Buffer* element_array_buffer =
[email protected]e259eb412012-10-13 05:47:249625 state_.vertex_attrib_manager->element_array_buffer();
[email protected]ab4fd7282012-10-12 16:25:579626 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
9627 element_array_buffer ? element_array_buffer->service_id() : 0);
[email protected]944b62f32012-09-27 02:20:469628}
9629
9630bool GLES2DecoderImpl::DoIsVertexArrayOES(GLuint client_id) {
[email protected]944b62f32012-09-27 02:20:469631 const VertexAttribManager* vao =
9632 GetVertexAttribManager(client_id);
9633 return vao && vao->IsValid() && !vao->IsDeleted();
9634}
9635
[email protected]b0af4f52011-09-28 22:04:429636error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM(
9637 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359638 const cmds::CreateStreamTextureCHROMIUM& c) {
[email protected]62e155e2012-10-23 22:43:159639 if (!features().chromium_stream_texture) {
[email protected]ab09b612013-03-11 22:11:519640 LOCAL_SET_GL_ERROR(
9641 GL_INVALID_OPERATION,
9642 "glOpenStreamTextureCHROMIUM", "not supported.");
[email protected]b0af4f52011-09-28 22:04:429643 return error::kNoError;
9644 }
9645
9646 uint32 client_id = c.client_id;
[email protected]ed9f9cd2013-02-27 21:12:359647 typedef cmds::CreateStreamTextureCHROMIUM::Result Result;
[email protected]b0af4f52011-09-28 22:04:429648 Result* result = GetSharedMemoryAs<Result*>(
9649 c.result_shm_id, c.result_shm_offset, sizeof(*result));
9650
[email protected]e5081262012-01-05 23:09:039651 if (!result)
9652 return error::kOutOfBounds;
[email protected]b0af4f52011-09-28 22:04:429653 *result = GL_ZERO;
[email protected]370eaf12013-05-18 09:19:499654 TextureRef* texture_ref = texture_manager()->GetTexture(client_id);
9655 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519656 LOCAL_SET_GL_ERROR(
9657 GL_INVALID_VALUE,
9658 "glCreateStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429659 return error::kNoError;
9660 }
9661
[email protected]370eaf12013-05-18 09:19:499662 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079663 if (texture->IsStreamTexture()) {
[email protected]ab09b612013-03-11 22:11:519664 LOCAL_SET_GL_ERROR(
9665 GL_INVALID_OPERATION,
9666 "glCreateStreamTextureCHROMIUM", "is already a stream texture.");
[email protected]b0af4f52011-09-28 22:04:429667 return error::kNoError;
9668 }
9669
[email protected]02965c22013-03-09 02:40:079670 if (texture->target() && texture->target() != GL_TEXTURE_EXTERNAL_OES) {
[email protected]ab09b612013-03-11 22:11:519671 LOCAL_SET_GL_ERROR(
9672 GL_INVALID_OPERATION,
9673 "glCreateStreamTextureCHROMIUM",
9674 "is already bound to incompatible target.");
[email protected]b0af4f52011-09-28 22:04:429675 return error::kNoError;
9676 }
9677
[email protected]4f9958142013-07-02 03:58:079678 if (!stream_texture_manager())
[email protected]b0af4f52011-09-28 22:04:429679 return error::kInvalidArguments;
9680
[email protected]4f9958142013-07-02 03:58:079681 GLuint object_id = stream_texture_manager()->CreateStreamTexture(
[email protected]02965c22013-03-09 02:40:079682 texture->service_id(), client_id);
[email protected]b0af4f52011-09-28 22:04:429683
9684 if (object_id) {
[email protected]370eaf12013-05-18 09:19:499685 texture_manager()->SetStreamTexture(texture_ref, true);
[email protected]b0af4f52011-09-28 22:04:429686 } else {
[email protected]ab09b612013-03-11 22:11:519687 LOCAL_SET_GL_ERROR(
9688 GL_OUT_OF_MEMORY,
9689 "glCreateStreamTextureCHROMIUM", "failed to create platform texture.");
[email protected]b0af4f52011-09-28 22:04:429690 }
9691
9692 *result = object_id;
9693 return error::kNoError;
9694}
9695
9696error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM(
9697 uint32 immediate_data_size,
[email protected]ed9f9cd2013-02-27 21:12:359698 const cmds::DestroyStreamTextureCHROMIUM& c) {
[email protected]b0af4f52011-09-28 22:04:429699 GLuint client_id = c.texture;
[email protected]370eaf12013-05-18 09:19:499700 TextureRef* texture_ref = texture_manager()->GetTexture(client_id);
[email protected]4f9958142013-07-02 03:58:079701 if (texture_ref && texture_manager()->IsStreamTextureOwner(texture_ref)) {
9702 if (!stream_texture_manager())
[email protected]b0af4f52011-09-28 22:04:429703 return error::kInvalidArguments;
9704
[email protected]4f9958142013-07-02 03:58:079705 stream_texture_manager()->DestroyStreamTexture(texture_ref->service_id());
[email protected]370eaf12013-05-18 09:19:499706 texture_manager()->SetStreamTexture(texture_ref, false);
[email protected]b0af4f52011-09-28 22:04:429707 } else {
[email protected]ab09b612013-03-11 22:11:519708 LOCAL_SET_GL_ERROR(
9709 GL_INVALID_VALUE,
9710 "glDestroyStreamTextureCHROMIUM", "bad texture id.");
[email protected]b0af4f52011-09-28 22:04:429711 }
9712
9713 return error::kNoError;
9714}
9715
[email protected]e51bdf32011-11-23 22:21:469716#if defined(OS_MACOSX)
9717void GLES2DecoderImpl::ReleaseIOSurfaceForTexture(GLuint texture_id) {
9718 TextureToIOSurfaceMap::iterator it = texture_to_io_surface_map_.find(
9719 texture_id);
9720 if (it != texture_to_io_surface_map_.end()) {
9721 // Found a previous IOSurface bound to this texture; release it.
9722 CFTypeRef surface = it->second;
9723 CFRelease(surface);
9724 texture_to_io_surface_map_.erase(it);
9725 }
9726}
9727#endif
9728
9729void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
9730 GLenum target, GLsizei width, GLsizei height,
9731 GLuint io_surface_id, GLuint plane) {
9732#if defined(OS_MACOSX)
9733 if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL) {
[email protected]ab09b612013-03-11 22:11:519734 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439735 GL_INVALID_OPERATION,
9736 "glTexImageIOSurface2DCHROMIUM", "only supported on desktop GL.");
[email protected]e51bdf32011-11-23 22:21:469737 return;
9738 }
9739
9740 IOSurfaceSupport* surface_support = IOSurfaceSupport::Initialize();
9741 if (!surface_support) {
[email protected]ab09b612013-03-11 22:11:519742 LOCAL_SET_GL_ERROR(
9743 GL_INVALID_OPERATION,
9744 "glTexImageIOSurface2DCHROMIUM", "only supported on 10.6.");
[email protected]e51bdf32011-11-23 22:21:469745 return;
9746 }
9747
9748 if (target != GL_TEXTURE_RECTANGLE_ARB) {
9749 // This might be supported in the future, and if we could require
9750 // support for binding an IOSurface to a NPOT TEXTURE_2D texture, we
9751 // could delete a lot of code. For now, perform strict validation so we
9752 // know what's going on.
[email protected]ab09b612013-03-11 22:11:519753 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469754 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439755 "glTexImageIOSurface2DCHROMIUM",
9756 "requires TEXTURE_RECTANGLE_ARB target");
[email protected]e51bdf32011-11-23 22:21:469757 return;
9758 }
9759
[email protected]09d50362012-10-18 20:54:379760 // Default target might be conceptually valid, but disallow it to avoid
9761 // accidents.
[email protected]c986af502013-08-14 01:04:449762 TextureRef* texture_ref =
9763 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:499764 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:519765 LOCAL_SET_GL_ERROR(
9766 GL_INVALID_OPERATION,
9767 "glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
[email protected]e51bdf32011-11-23 22:21:469768 return;
9769 }
[email protected]e51bdf32011-11-23 22:21:469770
9771 // Look up the new IOSurface. Note that because of asynchrony
9772 // between processes this might fail; during live resizing the
9773 // plugin process might allocate and release an IOSurface before
9774 // this process gets a chance to look it up. Hold on to any old
9775 // IOSurface in this case.
9776 CFTypeRef surface = surface_support->IOSurfaceLookup(io_surface_id);
9777 if (!surface) {
[email protected]ab09b612013-03-11 22:11:519778 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:439779 GL_INVALID_OPERATION,
9780 "glTexImageIOSurface2DCHROMIUM", "no IOSurface with the given ID");
[email protected]e51bdf32011-11-23 22:21:469781 return;
9782 }
9783
9784 // Release any IOSurface previously bound to this texture.
[email protected]370eaf12013-05-18 09:19:499785 ReleaseIOSurfaceForTexture(texture_ref->service_id());
[email protected]e51bdf32011-11-23 22:21:469786
9787 // Make sure we release the IOSurface even if CGLTexImageIOSurface2D fails.
9788 texture_to_io_surface_map_.insert(
[email protected]370eaf12013-05-18 09:19:499789 std::make_pair(texture_ref->service_id(), surface));
[email protected]e51bdf32011-11-23 22:21:469790
9791 CGLContextObj context =
9792 static_cast<CGLContextObj>(context_->GetHandle());
9793
9794 CGLError err = surface_support->CGLTexImageIOSurface2D(
9795 context,
9796 target,
9797 GL_RGBA,
9798 width,
9799 height,
9800 GL_BGRA,
9801 GL_UNSIGNED_INT_8_8_8_8_REV,
9802 surface,
9803 plane);
9804
9805 if (err != kCGLNoError) {
[email protected]ab09b612013-03-11 22:11:519806 LOCAL_SET_GL_ERROR(
[email protected]e51bdf32011-11-23 22:21:469807 GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439808 "glTexImageIOSurface2DCHROMIUM", "error in CGLTexImageIOSurface2D");
[email protected]e51bdf32011-11-23 22:21:469809 return;
9810 }
9811
9812 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499813 texture_ref, target, 0, GL_RGBA, width, height, 1, 0,
[email protected]e51bdf32011-11-23 22:21:469814 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true);
9815
9816#else
[email protected]ab09b612013-03-11 22:11:519817 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
[email protected]ad84a3a2012-06-08 21:42:439818 "glTexImageIOSurface2DCHROMIUM", "not supported.");
[email protected]e51bdf32011-11-23 22:21:469819#endif
9820}
9821
[email protected]97dc7cbe2011-12-06 17:26:179822static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
9823 switch (internalformat) {
9824 case GL_RGB565:
9825 return GL_RGB;
9826 case GL_RGBA4:
9827 return GL_RGBA;
9828 case GL_RGB5_A1:
9829 return GL_RGBA;
9830 case GL_RGB8_OES:
9831 return GL_RGB;
9832 case GL_RGBA8_OES:
9833 return GL_RGBA;
9834 case GL_LUMINANCE8_ALPHA8_EXT:
9835 return GL_LUMINANCE_ALPHA;
9836 case GL_LUMINANCE8_EXT:
9837 return GL_LUMINANCE;
9838 case GL_ALPHA8_EXT:
9839 return GL_ALPHA;
9840 case GL_RGBA32F_EXT:
9841 return GL_RGBA;
9842 case GL_RGB32F_EXT:
9843 return GL_RGB;
9844 case GL_ALPHA32F_EXT:
9845 return GL_ALPHA;
9846 case GL_LUMINANCE32F_EXT:
9847 return GL_LUMINANCE;
9848 case GL_LUMINANCE_ALPHA32F_EXT:
9849 return GL_LUMINANCE_ALPHA;
9850 case GL_RGBA16F_EXT:
9851 return GL_RGBA;
9852 case GL_RGB16F_EXT:
9853 return GL_RGB;
9854 case GL_ALPHA16F_EXT:
9855 return GL_ALPHA;
9856 case GL_LUMINANCE16F_EXT:
9857 return GL_LUMINANCE;
9858 case GL_LUMINANCE_ALPHA16F_EXT:
9859 return GL_LUMINANCE_ALPHA;
9860 case GL_BGRA8_EXT:
9861 return GL_BGRA_EXT;
9862 default:
9863 return GL_NONE;
9864 }
9865}
9866
[email protected]43410e92012-04-20 17:06:289867void GLES2DecoderImpl::DoCopyTextureCHROMIUM(
[email protected]0a1e9ad2012-05-04 21:13:039868 GLenum target, GLuint source_id, GLuint dest_id, GLint level,
[email protected]a4a6bdd12013-04-19 20:46:549869 GLenum internal_format, GLenum dest_type) {
[email protected]370eaf12013-05-18 09:19:499870 TextureRef* dest_texture_ref = GetTexture(dest_id);
9871 TextureRef* source_texture_ref = GetTexture(source_id);
[email protected]43410e92012-04-20 17:06:289872
[email protected]370eaf12013-05-18 09:19:499873 if (!source_texture_ref || !dest_texture_ref) {
[email protected]ab09b612013-03-11 22:11:519874 LOCAL_SET_GL_ERROR(
9875 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "unknown texture id");
[email protected]43410e92012-04-20 17:06:289876 return;
9877 }
9878
9879 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:519880 LOCAL_SET_GL_ERROR(
9881 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "invalid texture target");
[email protected]43410e92012-04-20 17:06:289882 return;
9883 }
9884
[email protected]370eaf12013-05-18 09:19:499885 Texture* source_texture = source_texture_ref->texture();
9886 Texture* dest_texture = dest_texture_ref->texture();
[email protected]02965c22013-03-09 02:40:079887 if (dest_texture->target() != GL_TEXTURE_2D ||
[email protected]9bc9a2e82013-04-03 03:56:259888 (source_texture->target() != GL_TEXTURE_2D &&
9889 source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) {
[email protected]3ecc1052013-09-26 08:59:009890 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
9891 "glCopyTextureCHROMIUM",
9892 "invalid texture target binding");
[email protected]0a1e9ad2012-05-04 21:13:039893 return;
9894 }
9895
[email protected]43410e92012-04-20 17:06:289896 int source_width, source_height, dest_width, dest_height;
[email protected]43410e92012-04-20 17:06:289897
[email protected]3ecc1052013-09-26 08:59:009898 if (source_texture->IsStreamTexture()) {
9899 DCHECK_EQ(source_texture->target(),
9900 static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES));
[email protected]4f9958142013-07-02 03:58:079901 DCHECK(stream_texture_manager());
[email protected]377976552013-05-14 23:32:569902 StreamTexture* stream_tex =
[email protected]4f9958142013-07-02 03:58:079903 stream_texture_manager()->LookupStreamTexture(
[email protected]377976552013-05-14 23:32:569904 source_texture->service_id());
9905 if (!stream_tex) {
9906 LOCAL_SET_GL_ERROR(
9907 GL_INVALID_VALUE,
9908 "glCopyTextureChromium", "Stream texture lookup failed");
9909 return;
9910 }
9911 gfx::Size size = stream_tex->GetSize();
9912 source_width = size.width();
9913 source_height = size.height();
9914 if (source_width <= 0 || source_height <= 0) {
9915 LOCAL_SET_GL_ERROR(
9916 GL_INVALID_VALUE,
9917 "glCopyTextureChromium", "invalid streamtexture size");
9918 return;
9919 }
[email protected]3ecc1052013-09-26 08:59:009920 } else {
9921 if (!source_texture->GetLevelSize(
9922 source_texture->target(), 0, &source_width, &source_height)) {
9923 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
9924 "glCopyTextureChromium",
9925 "source texture has no level 0");
9926 return;
9927 }
9928
9929 // Check that this type of texture is allowed.
9930 if (!texture_manager()->ValidForTarget(
9931 source_texture->target(), level, source_width, source_height, 1)) {
9932 LOCAL_SET_GL_ERROR(
9933 GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions");
9934 return;
9935 }
[email protected]377976552013-05-14 23:32:569936 }
9937
[email protected]cf6b8f62012-05-25 21:43:379938 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is
9939 // needed because it takes 10s of milliseconds to initialize.
9940 if (!copy_texture_CHROMIUM_.get()) {
[email protected]ab09b612013-03-11 22:11:519941 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]cf6b8f62012-05-25 21:43:379942 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager());
[email protected]07a0cc32013-02-28 00:36:279943 copy_texture_CHROMIUM_->Initialize(this);
[email protected]cf6b8f62012-05-25 21:43:379944 RestoreCurrentFramebufferBindings();
[email protected]ab09b612013-03-11 22:11:519945 if (LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM") != GL_NO_ERROR)
[email protected]cf6b8f62012-05-25 21:43:379946 return;
9947 }
9948
[email protected]a4a6bdd12013-04-19 20:46:549949 GLenum dest_type_previous;
[email protected]0a1e9ad2012-05-04 21:13:039950 GLenum dest_internal_format;
[email protected]02965c22013-03-09 02:40:079951 bool dest_level_defined = dest_texture->GetLevelSize(
9952 GL_TEXTURE_2D, level, &dest_width, &dest_height);
[email protected]43410e92012-04-20 17:06:289953
[email protected]0a1e9ad2012-05-04 21:13:039954 if (dest_level_defined) {
[email protected]a4a6bdd12013-04-19 20:46:549955 dest_texture->GetLevelType(GL_TEXTURE_2D, level, &dest_type_previous,
[email protected]02965c22013-03-09 02:40:079956 &dest_internal_format);
[email protected]0a1e9ad2012-05-04 21:13:039957 }
9958
9959 // Resize the destination texture to the dimensions of the source texture.
9960 if (!dest_level_defined || dest_width != source_width ||
9961 dest_height != source_height ||
[email protected]a4a6bdd12013-04-19 20:46:549962 dest_internal_format != internal_format ||
9963 dest_type_previous != dest_type) {
[email protected]43410e92012-04-20 17:06:289964 // Ensure that the glTexImage2D succeeds.
[email protected]ab09b612013-03-11 22:11:519965 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM");
[email protected]02965c22013-03-09 02:40:079966 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id());
[email protected]8f1d2aa2013-05-10 23:45:389967 glTexImage2D(
[email protected]43410e92012-04-20 17:06:289968 GL_TEXTURE_2D, level, internal_format, source_width, source_height,
[email protected]0a1e9ad2012-05-04 21:13:039969 0, internal_format, dest_type, NULL);
[email protected]ab09b612013-03-11 22:11:519970 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM");
[email protected]0a1e9ad2012-05-04 21:13:039971 if (error != GL_NO_ERROR) {
[email protected]ce296892013-10-24 22:04:369972 RestoreCurrentTexture2DBindings(&state_);
[email protected]43410e92012-04-20 17:06:289973 return;
[email protected]0a1e9ad2012-05-04 21:13:039974 }
[email protected]43410e92012-04-20 17:06:289975
9976 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:499977 dest_texture_ref, GL_TEXTURE_2D, level, internal_format, source_width,
[email protected]0a1e9ad2012-05-04 21:13:039978 source_height, 1, 0, internal_format, dest_type, true);
[email protected]f7024712012-05-15 21:30:259979 } else {
[email protected]02965c22013-03-09 02:40:079980 texture_manager()->SetLevelCleared(
[email protected]370eaf12013-05-18 09:19:499981 dest_texture_ref, GL_TEXTURE_2D, level, true);
[email protected]43410e92012-04-20 17:06:289982 }
9983
[email protected]91c94eb2013-10-22 10:32:549984 DoWillUseTexImageIfNeeded(source_texture, source_texture->target());
9985
[email protected]5394a4102013-04-18 05:41:379986 // GL_TEXTURE_EXTERNAL_OES texture requires apply a transform matrix
9987 // before presenting.
9988 if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) {
9989 // TODO(hkuang): get the StreamTexture transform matrix in GPU process
9990 // instead of using default matrix crbug.com/226218.
9991 const static GLfloat default_matrix[16] = {1.0f, 0.0f, 0.0f, 0.0f,
9992 0.0f, 1.0f, 0.0f, 0.0f,
9993 0.0f, 0.0f, 1.0f, 0.0f,
9994 0.0f, 0.0f, 0.0f, 1.0f};
9995 copy_texture_CHROMIUM_->DoCopyTextureWithTransform(
9996 this,
9997 source_texture->target(),
9998 dest_texture->target(),
9999 source_texture->service_id(),
10000 dest_texture->service_id(), level,
10001 source_width, source_height,
10002 unpack_flip_y_,
10003 unpack_premultiply_alpha_,
10004 unpack_unpremultiply_alpha_,
10005 default_matrix);
10006 } else {
10007 copy_texture_CHROMIUM_->DoCopyTexture(
10008 this,
10009 source_texture->target(),
10010 dest_texture->target(),
10011 source_texture->service_id(),
10012 dest_texture->service_id(), level,
10013 source_width, source_height,
10014 unpack_flip_y_,
10015 unpack_premultiply_alpha_,
10016 unpack_unpremultiply_alpha_);
10017 }
[email protected]91c94eb2013-10-22 10:32:5410018
10019 DoDidUseTexImageIfNeeded(source_texture, source_texture->target());
[email protected]43410e92012-04-20 17:06:2810020}
10021
[email protected]97dc7cbe2011-12-06 17:26:1710022static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
10023 switch (internalformat) {
10024 case GL_RGB565:
10025 return GL_UNSIGNED_SHORT_5_6_5;
10026 case GL_RGBA4:
10027 return GL_UNSIGNED_SHORT_4_4_4_4;
10028 case GL_RGB5_A1:
10029 return GL_UNSIGNED_SHORT_5_5_5_1;
10030 case GL_RGB8_OES:
10031 return GL_UNSIGNED_BYTE;
10032 case GL_RGBA8_OES:
10033 return GL_UNSIGNED_BYTE;
10034 case GL_LUMINANCE8_ALPHA8_EXT:
10035 return GL_UNSIGNED_BYTE;
10036 case GL_LUMINANCE8_EXT:
10037 return GL_UNSIGNED_BYTE;
10038 case GL_ALPHA8_EXT:
10039 return GL_UNSIGNED_BYTE;
10040 case GL_RGBA32F_EXT:
10041 return GL_FLOAT;
10042 case GL_RGB32F_EXT:
10043 return GL_FLOAT;
10044 case GL_ALPHA32F_EXT:
10045 return GL_FLOAT;
10046 case GL_LUMINANCE32F_EXT:
10047 return GL_FLOAT;
10048 case GL_LUMINANCE_ALPHA32F_EXT:
10049 return GL_FLOAT;
10050 case GL_RGBA16F_EXT:
10051 return GL_HALF_FLOAT_OES;
10052 case GL_RGB16F_EXT:
10053 return GL_HALF_FLOAT_OES;
10054 case GL_ALPHA16F_EXT:
10055 return GL_HALF_FLOAT_OES;
10056 case GL_LUMINANCE16F_EXT:
10057 return GL_HALF_FLOAT_OES;
10058 case GL_LUMINANCE_ALPHA16F_EXT:
10059 return GL_HALF_FLOAT_OES;
10060 case GL_BGRA8_EXT:
10061 return GL_UNSIGNED_BYTE;
10062 default:
10063 return GL_NONE;
10064 }
10065}
10066
10067void GLES2DecoderImpl::DoTexStorage2DEXT(
[email protected]a5d3dad2012-05-26 04:34:4410068 GLenum target,
10069 GLint levels,
10070 GLenum internal_format,
10071 GLsizei width,
10072 GLsizei height) {
[email protected]43ed3a72012-05-30 22:55:3810073 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT");
[email protected]80eb6b52012-01-19 00:14:4110074 if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) ||
[email protected]3ecc1052013-09-26 08:59:0010075 TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) {
[email protected]ab09b612013-03-11 22:11:5110076 LOCAL_SET_GL_ERROR(
[email protected]ad84a3a2012-06-08 21:42:4310077 GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range");
[email protected]97dc7cbe2011-12-06 17:26:1710078 return;
10079 }
[email protected]c986af502013-08-14 01:04:4410080 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10081 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910082 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110083 LOCAL_SET_GL_ERROR(
10084 GL_INVALID_OPERATION,
10085 "glTexStorage2DEXT", "unknown texture for target");
[email protected]97dc7cbe2011-12-06 17:26:1710086 return;
10087 }
[email protected]370eaf12013-05-18 09:19:4910088 Texture* texture = texture_ref->texture();
[email protected]02965c22013-03-09 02:40:0710089 if (texture->IsAttachedToFramebuffer()) {
[email protected]c986af502013-08-14 01:04:4410090 framebuffer_state_.clear_state_dirty = true;
[email protected]97dc7cbe2011-12-06 17:26:1710091 }
[email protected]02965c22013-03-09 02:40:0710092 if (texture->IsImmutable()) {
[email protected]ab09b612013-03-11 22:11:5110093 LOCAL_SET_GL_ERROR(
10094 GL_INVALID_OPERATION,
10095 "glTexStorage2DEXT", "texture is immutable");
[email protected]97dc7cbe2011-12-06 17:26:1710096 return;
10097 }
[email protected]7989c9e2013-01-23 06:39:2610098
10099 GLenum format = ExtractFormatFromStorageFormat(internal_format);
10100 GLenum type = ExtractTypeFromStorageFormat(internal_format);
10101
10102 {
10103 GLsizei level_width = width;
10104 GLsizei level_height = height;
10105 uint32 estimated_size = 0;
10106 for (int ii = 0; ii < levels; ++ii) {
10107 uint32 level_size = 0;
10108 if (!GLES2Util::ComputeImageDataSizes(
10109 level_width, level_height, format, type, state_.unpack_alignment,
10110 &estimated_size, NULL, NULL) ||
10111 !SafeAddUint32(estimated_size, level_size, &estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110112 LOCAL_SET_GL_ERROR(
10113 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "dimensions too large");
[email protected]7989c9e2013-01-23 06:39:2610114 return;
10115 }
10116 level_width = std::max(1, level_width >> 1);
10117 level_height = std::max(1, level_height >> 1);
10118 }
10119 if (!EnsureGPUMemoryAvailable(estimated_size)) {
[email protected]ab09b612013-03-11 22:11:5110120 LOCAL_SET_GL_ERROR(
10121 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610122 return;
10123 }
10124 }
10125
[email protected]ab09b612013-03-11 22:11:5110126 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT");
[email protected]8f1d2aa2013-05-10 23:45:3810127 glTexStorage2DEXT(target, levels, internal_format, width, height);
[email protected]ab09b612013-03-11 22:11:5110128 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT");
[email protected]97dc7cbe2011-12-06 17:26:1710129 if (error == GL_NO_ERROR) {
[email protected]4502e6492011-12-14 19:39:1510130 GLsizei level_width = width;
10131 GLsizei level_height = height;
10132 for (int ii = 0; ii < levels; ++ii) {
10133 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910134 texture_ref, target, ii, format,
10135 level_width, level_height, 1, 0, format, type, false);
[email protected]4502e6492011-12-14 19:39:1510136 level_width = std::max(1, level_width >> 1);
10137 level_height = std::max(1, level_height >> 1);
10138 }
[email protected]02965c22013-03-09 02:40:0710139 texture->SetImmutable(true);
[email protected]97dc7cbe2011-12-06 17:26:1710140 }
[email protected]97dc7cbe2011-12-06 17:26:1710141}
[email protected]e51bdf32011-11-23 22:21:4610142
[email protected]78b514b2012-05-01 21:50:5910143error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510144 uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) {
[email protected]baed42c2013-10-01 05:06:3510145 return error::kUnknownCommand;
[email protected]78b514b2012-05-01 21:50:5910146}
10147
10148void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target,
10149 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:0210150 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210151 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:0210152 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
10153
[email protected]c986af502013-08-14 01:04:4410154 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10155 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910156 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110157 LOCAL_SET_GL_ERROR(
10158 GL_INVALID_OPERATION,
10159 "glProduceTextureCHROMIUM", "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910160 return;
10161 }
10162
[email protected]62e65f02013-05-29 22:28:1010163 Texture* produced = texture_manager()->Produce(texture_ref);
10164 if (!produced) {
[email protected]ab09b612013-03-11 22:11:5110165 LOCAL_SET_GL_ERROR(
10166 GL_INVALID_OPERATION,
10167 "glProduceTextureCHROMIUM", "invalid texture");
[email protected]78b514b2012-05-01 21:50:5910168 return;
10169 }
10170
10171 if (!group_->mailbox_manager()->ProduceTexture(
10172 target,
10173 *reinterpret_cast<const MailboxName*>(mailbox),
[email protected]62e65f02013-05-29 22:28:1010174 produced)) {
[email protected]ab09b612013-03-11 22:11:5110175 LOCAL_SET_GL_ERROR(
10176 GL_INVALID_OPERATION,
10177 "glProduceTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5910178 return;
10179 }
[email protected]78b514b2012-05-01 21:50:5910180}
10181
10182void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target,
10183 const GLbyte* mailbox) {
[email protected]987b9c02013-03-23 00:58:0210184 TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoConsumeTextureCHROMIUM",
[email protected]1d82e822013-04-10 21:32:3210185 "context", logger_.GetLogPrefix(),
[email protected]987b9c02013-03-23 00:58:0210186 "mailbox[0]", static_cast<unsigned char>(mailbox[0]));
10187
[email protected]62e65f02013-05-29 22:28:1010188 scoped_refptr<TextureRef> texture_ref =
[email protected]c986af502013-08-14 01:04:4410189 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]7cd76fd2013-06-02 21:11:1110190 if (!texture_ref.get()) {
10191 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
10192 "glConsumeTextureCHROMIUM",
10193 "unknown texture for target");
[email protected]78b514b2012-05-01 21:50:5910194 return;
10195 }
[email protected]62e65f02013-05-29 22:28:1010196 GLuint client_id = texture_ref->client_id();
10197 if (!client_id) {
10198 LOCAL_SET_GL_ERROR(
10199 GL_INVALID_OPERATION,
10200 "glConsumeTextureCHROMIUM", "unknown texture for target");
10201 return;
10202 }
10203 Texture* texture =
[email protected]78b514b2012-05-01 21:50:5910204 group_->mailbox_manager()->ConsumeTexture(
10205 target,
[email protected]62e65f02013-05-29 22:28:1010206 *reinterpret_cast<const MailboxName*>(mailbox));
10207 if (!texture) {
[email protected]ab09b612013-03-11 22:11:5110208 LOCAL_SET_GL_ERROR(
10209 GL_INVALID_OPERATION,
10210 "glConsumeTextureCHROMIUM", "invalid mailbox name");
[email protected]78b514b2012-05-01 21:50:5910211 return;
10212 }
[email protected]62e65f02013-05-29 22:28:1010213 if (texture->target() != target) {
[email protected]ab09b612013-03-11 22:11:5110214 LOCAL_SET_GL_ERROR(
10215 GL_INVALID_OPERATION,
[email protected]62e65f02013-05-29 22:28:1010216 "glConsumeTextureCHROMIUM", "invalid target");
[email protected]78b514b2012-05-01 21:50:5910217 return;
10218 }
[email protected]62e65f02013-05-29 22:28:1010219
10220 DeleteTexturesHelper(1, &client_id);
10221 texture_ref = texture_manager()->Consume(client_id, texture);
10222 glBindTexture(target, texture_ref->service_id());
10223
10224 TextureUnit& unit = state_.texture_units[state_.active_texture_unit];
10225 unit.bind_target = target;
10226 switch (target) {
10227 case GL_TEXTURE_2D:
10228 unit.bound_texture_2d = texture_ref;
10229 break;
10230 case GL_TEXTURE_CUBE_MAP:
10231 unit.bound_texture_cube_map = texture_ref;
10232 break;
10233 case GL_TEXTURE_EXTERNAL_OES:
10234 unit.bound_texture_external_oes = texture_ref;
10235 break;
10236 case GL_TEXTURE_RECTANGLE_ARB:
10237 unit.bound_texture_rectangle_arb = texture_ref;
10238 break;
10239 default:
10240 NOTREACHED(); // Validation should prevent us getting here.
10241 break;
10242 }
[email protected]78b514b2012-05-01 21:50:5910243}
10244
[email protected]d2a0e1a2012-08-12 02:25:0110245void GLES2DecoderImpl::DoInsertEventMarkerEXT(
10246 GLsizei length, const GLchar* marker) {
10247 if (!marker) {
10248 marker = "";
10249 }
10250 debug_marker_manager_.SetMarker(
10251 length ? std::string(marker, length) : std::string(marker));
10252}
10253
10254void GLES2DecoderImpl::DoPushGroupMarkerEXT(
10255 GLsizei length, const GLchar* marker) {
10256 if (!marker) {
10257 marker = "";
10258 }
[email protected]cac16542014-01-15 17:53:5110259 std::string name = length ? std::string(marker, length) : std::string(marker);
10260 debug_marker_manager_.PushGroup(name);
10261 gpu_tracer_->Begin(name, kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110262}
10263
10264void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
10265 debug_marker_manager_.PopGroup();
[email protected]cac16542014-01-15 17:53:5110266 gpu_tracer_->End(kTraceGroupMarker);
[email protected]d2a0e1a2012-08-12 02:25:0110267}
10268
[email protected]09d50362012-10-18 20:54:3710269void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
10270 GLenum target, GLint image_id) {
10271 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710272
10273 // Default target might be conceptually valid, but disallow it to avoid
10274 // accidents.
[email protected]c986af502013-08-14 01:04:4410275 TextureRef* texture_ref =
10276 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910277 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110278 LOCAL_SET_GL_ERROR(
10279 GL_INVALID_OPERATION,
10280 "glBindTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710281 return;
10282 }
10283
10284 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10285 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110286 LOCAL_SET_GL_ERROR(
10287 GL_INVALID_OPERATION,
10288 "glBindTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710289 return;
10290 }
10291
[email protected]b8160812013-04-09 00:41:0410292 {
10293 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010294 "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610295 if (!gl_image->BindTexImage(target)) {
[email protected]b8160812013-04-09 00:41:0410296 LOCAL_SET_GL_ERROR(
10297 GL_INVALID_OPERATION,
10298 "glBindTexImage2DCHROMIUM", "fail to bind image with the given ID");
10299 return;
10300 }
[email protected]09d50362012-10-18 20:54:3710301 }
10302
10303 gfx::Size size = gl_image->GetSize();
10304 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910305 texture_ref, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
[email protected]09d50362012-10-18 20:54:3710306 GL_RGBA, GL_UNSIGNED_BYTE, true);
[email protected]370eaf12013-05-18 09:19:4910307 texture_manager()->SetLevelImage(texture_ref, target, 0, gl_image);
[email protected]09d50362012-10-18 20:54:3710308}
10309
10310void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
10311 GLenum target, GLint image_id) {
10312 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
[email protected]09d50362012-10-18 20:54:3710313
10314 // Default target might be conceptually valid, but disallow it to avoid
10315 // accidents.
[email protected]c986af502013-08-14 01:04:4410316 TextureRef* texture_ref =
10317 texture_manager()->GetTextureInfoForTargetUnlessDefault(&state_, target);
[email protected]370eaf12013-05-18 09:19:4910318 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110319 LOCAL_SET_GL_ERROR(
10320 GL_INVALID_OPERATION,
10321 "glReleaseTexImage2DCHROMIUM", "no texture bound");
[email protected]09d50362012-10-18 20:54:3710322 return;
10323 }
10324
10325 gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
10326 if (!gl_image) {
[email protected]ab09b612013-03-11 22:11:5110327 LOCAL_SET_GL_ERROR(
10328 GL_INVALID_OPERATION,
10329 "glReleaseTexImage2DCHROMIUM", "no image found with the given ID");
[email protected]09d50362012-10-18 20:54:3710330 return;
10331 }
10332
10333 // Do nothing when image is not currently bound.
[email protected]370eaf12013-05-18 09:19:4910334 if (texture_ref->texture()->GetLevelImage(target, 0) != gl_image)
[email protected]09d50362012-10-18 20:54:3710335 return;
10336
[email protected]b8160812013-04-09 00:41:0410337 {
10338 ScopedGLErrorSuppressor suppressor(
[email protected]40621eb52013-10-08 15:40:3010339 "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM", GetErrorState());
[email protected]3c580122013-11-22 07:52:2610340 gl_image->ReleaseTexImage(target);
[email protected]b8160812013-04-09 00:41:0410341 }
[email protected]09d50362012-10-18 20:54:3710342
10343 texture_manager()->SetLevelInfo(
[email protected]370eaf12013-05-18 09:19:4910344 texture_ref, target, 0, GL_RGBA, 0, 0, 1, 0,
[email protected]09d50362012-10-18 20:54:3710345 GL_RGBA, GL_UNSIGNED_BYTE, false);
10346}
[email protected]d2a0e1a2012-08-12 02:25:0110347
[email protected]94307712012-11-16 23:26:1110348error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510349 uint32 immediate_data_size, const cmds::TraceBeginCHROMIUM& c) {
[email protected]94307712012-11-16 23:26:1110350 Bucket* bucket = GetBucket(c.bucket_id);
10351 if (!bucket || bucket->size() == 0) {
10352 return error::kInvalidArguments;
10353 }
10354 std::string command_name;
10355 if (!bucket->GetAsString(&command_name)) {
10356 return error::kInvalidArguments;
10357 }
[email protected]fb97b662013-02-20 23:02:1410358 TRACE_EVENT_COPY_ASYNC_BEGIN0("gpu", command_name.c_str(), this);
[email protected]cac16542014-01-15 17:53:5110359 if (!gpu_tracer_->Begin(command_name, kTraceCHROMIUM)) {
[email protected]ab09b612013-03-11 22:11:5110360 LOCAL_SET_GL_ERROR(
10361 GL_INVALID_OPERATION,
10362 "glTraceBeginCHROMIUM", "unable to create begin trace");
[email protected]fb97b662013-02-20 23:02:1410363 return error::kNoError;
10364 }
[email protected]94307712012-11-16 23:26:1110365 return error::kNoError;
10366}
10367
10368void GLES2DecoderImpl::DoTraceEndCHROMIUM() {
[email protected]fb97b662013-02-20 23:02:1410369 if (gpu_tracer_->CurrentName().empty()) {
[email protected]ab09b612013-03-11 22:11:5110370 LOCAL_SET_GL_ERROR(
10371 GL_INVALID_OPERATION,
10372 "glTraceEndCHROMIUM", "no trace begin found");
[email protected]94307712012-11-16 23:26:1110373 return;
10374 }
[email protected]fb97b662013-02-20 23:02:1410375 TRACE_EVENT_COPY_ASYNC_END0("gpu", gpu_tracer_->CurrentName().c_str(), this);
[email protected]cac16542014-01-15 17:53:5110376 gpu_tracer_->End(kTraceCHROMIUM);
[email protected]94307712012-11-16 23:26:1110377}
10378
[email protected]2f143d482013-03-14 18:04:4910379void GLES2DecoderImpl::DoDrawBuffersEXT(
10380 GLsizei count, const GLenum* bufs) {
10381 if (count > static_cast<GLsizei>(group_->max_draw_buffers())) {
10382 LOCAL_SET_GL_ERROR(
10383 GL_INVALID_VALUE,
10384 "glDrawBuffersEXT", "greater than GL_MAX_DRAW_BUFFERS_EXT");
10385 return;
10386 }
10387
10388 Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_FRAMEBUFFER);
10389 if (framebuffer) {
10390 for (GLsizei i = 0; i < count; ++i) {
10391 if (bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + i) &&
10392 bufs[i] != GL_NONE) {
10393 LOCAL_SET_GL_ERROR(
10394 GL_INVALID_OPERATION,
10395 "glDrawBuffersEXT",
10396 "bufs[i] not GL_NONE or GL_COLOR_ATTACHMENTi_EXT");
10397 return;
10398 }
10399 }
10400 glDrawBuffersARB(count, bufs);
10401 framebuffer->SetDrawBuffers(count, bufs);
10402 } else { // backbuffer
10403 if (count > 1 ||
10404 (bufs[0] != GL_BACK && bufs[0] != GL_NONE)) {
10405 LOCAL_SET_GL_ERROR(
10406 GL_INVALID_OPERATION,
10407 "glDrawBuffersEXT",
10408 "more than one buffer or bufs not GL_NONE or GL_BACK");
10409 return;
10410 }
10411 GLenum mapped_buf = bufs[0];
10412 if (GetBackbufferServiceId() != 0 && // emulated backbuffer
10413 bufs[0] == GL_BACK) {
10414 mapped_buf = GL_COLOR_ATTACHMENT0;
10415 }
10416 glDrawBuffersARB(count, &mapped_buf);
10417 group_->set_draw_buffer(bufs[0]);
10418 }
10419}
10420
[email protected]32145a92012-12-17 09:01:5910421bool GLES2DecoderImpl::ValidateAsyncTransfer(
10422 const char* function_name,
[email protected]85a4ac22013-05-31 01:58:4710423 TextureRef* texture_ref,
[email protected]32145a92012-12-17 09:01:5910424 GLenum target,
10425 GLint level,
10426 const void * data) {
10427 // We only support async uploads to 2D textures for now.
10428 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110429 LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, target, "target");
[email protected]32145a92012-12-17 09:01:5910430 return false;
10431 }
10432 // We only support uploads to level zero for now.
10433 if (level != 0) {
[email protected]ab09b612013-03-11 22:11:5110434 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "level != 0");
[email protected]32145a92012-12-17 09:01:5910435 return false;
10436 }
10437 // A transfer buffer must be bound, even for asyncTexImage2D.
10438 if (data == NULL) {
[email protected]ab09b612013-03-11 22:11:5110439 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, "buffer == 0");
[email protected]32145a92012-12-17 09:01:5910440 return false;
10441 }
10442 // We only support one async transfer in progress.
[email protected]85a4ac22013-05-31 01:58:4710443 if (!texture_ref ||
10444 async_pixel_transfer_manager_->AsyncTransferIsInProgress(texture_ref)) {
[email protected]ab09b612013-03-11 22:11:5110445 LOCAL_SET_GL_ERROR(
10446 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910447 function_name, "transfer already in progress");
10448 return false;
10449 }
10450 return true;
10451}
10452
[email protected]69023942012-11-30 19:57:1610453error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510454 uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610455 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610456 GLenum target = static_cast<GLenum>(c.target);
10457 GLint level = static_cast<GLint>(c.level);
[email protected]c986af502013-08-14 01:04:4410458 // TODO(kloveless): Change HandleAsyncTexImage2DCHROMIUM command to use
10459 // unsigned integer for internalformat.
10460 GLenum internal_format = static_cast<GLenum>(c.internalformat);
[email protected]69023942012-11-30 19:57:1610461 GLsizei width = static_cast<GLsizei>(c.width);
10462 GLsizei height = static_cast<GLsizei>(c.height);
10463 GLint border = static_cast<GLint>(c.border);
10464 GLenum format = static_cast<GLenum>(c.format);
10465 GLenum type = static_cast<GLenum>(c.type);
10466 uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
10467 uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
10468 uint32 pixels_size;
[email protected]32145a92012-12-17 09:01:5910469
10470 // TODO(epenner): Move this and copies of this memory validation
10471 // into ValidateTexImage2D step.
[email protected]69023942012-11-30 19:57:1610472 if (!GLES2Util::ComputeImageDataSizes(
10473 width, height, format, type, state_.unpack_alignment, &pixels_size, NULL,
10474 NULL)) {
10475 return error::kOutOfBounds;
10476 }
10477 const void* pixels = NULL;
10478 if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
10479 pixels = GetSharedMemoryAs<const void*>(
10480 pixels_shm_id, pixels_shm_offset, pixels_size);
10481 if (!pixels) {
10482 return error::kOutOfBounds;
10483 }
10484 }
10485
[email protected]c986af502013-08-14 01:04:4410486 TextureManager::DoTextImage2DArguments args = {
10487 target, level, internal_format, width, height, border, format, type,
10488 pixels, pixels_size};
10489 TextureRef* texture_ref;
[email protected]32145a92012-12-17 09:01:5910490 // All the normal glTexSubImage2D validation.
[email protected]c986af502013-08-14 01:04:4410491 if (!texture_manager()->ValidateTexImage2D(
10492 &state_, "glAsyncTexImage2DCHROMIUM", args, &texture_ref)) {
[email protected]32145a92012-12-17 09:01:5910493 return error::kNoError;
10494 }
10495
10496 // Extra async validation.
[email protected]370eaf12013-05-18 09:19:4910497 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910498 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710499 "glAsyncTexImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910500 return error::kNoError;
10501
10502 // Don't allow async redefinition of a textures.
[email protected]02965c22013-03-09 02:40:0710503 if (texture->IsDefined()) {
[email protected]ab09b612013-03-11 22:11:5110504 LOCAL_SET_GL_ERROR(
10505 GL_INVALID_OPERATION,
[email protected]32145a92012-12-17 09:01:5910506 "glAsyncTexImage2DCHROMIUM", "already defined");
10507 return error::kNoError;
10508 }
10509
[email protected]7989c9e2013-01-23 06:39:2610510 if (!EnsureGPUMemoryAvailable(pixels_size)) {
[email protected]ab09b612013-03-11 22:11:5110511 LOCAL_SET_GL_ERROR(
10512 GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory");
[email protected]7989c9e2013-01-23 06:39:2610513 return error::kNoError;
10514 }
10515
[email protected]32145a92012-12-17 09:01:5910516 // We know the memory/size is safe, so get the real shared memory since
10517 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110518 gpu::Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id);
[email protected]32145a92012-12-17 09:01:5910519 base::SharedMemory* shared_memory = buffer.shared_memory;
10520 uint32 shm_size = buffer.size;
10521 uint32 shm_data_offset = c.pixels_shm_offset;
10522 uint32 shm_data_size = pixels_size;
10523
[email protected]5b3a8e02013-03-13 05:36:4410524 // Setup the parameters.
[email protected]8f1d2aa2013-05-10 23:45:3810525 AsyncTexImage2DParams tex_params = {
10526 target, level, static_cast<GLenum>(internal_format),
10527 width, height, border, format, type};
10528 AsyncMemoryParams mem_params = {
10529 shared_memory, shm_size, shm_data_offset, shm_data_size};
[email protected]32145a92012-12-17 09:01:5910530
[email protected]5b3a8e02013-03-13 05:36:4410531 // Set up the async state if needed, and make the texture
10532 // immutable so the async state stays valid. The level info
10533 // is set up lazily when the transfer completes.
[email protected]896425e2013-06-12 17:27:1810534 AsyncPixelTransferDelegate* delegate =
10535 async_pixel_transfer_manager_->CreatePixelTransferDelegate(texture_ref,
10536 tex_params);
[email protected]5b3a8e02013-03-13 05:36:4410537 texture->SetImmutable(true);
[email protected]32145a92012-12-17 09:01:5910538
[email protected]896425e2013-06-12 17:27:1810539 delegate->AsyncTexImage2D(
[email protected]5b3a8e02013-03-13 05:36:4410540 tex_params,
10541 mem_params,
10542 base::Bind(&TextureManager::SetLevelInfoFromParams,
[email protected]370eaf12013-05-18 09:19:4910543 // The callback is only invoked if the transfer delegate still
10544 // exists, which implies through manager->texture_ref->state
[email protected]5b3a8e02013-03-13 05:36:4410545 // ownership that both of these pointers are valid.
10546 base::Unretained(texture_manager()),
[email protected]370eaf12013-05-18 09:19:4910547 base::Unretained(texture_ref),
[email protected]5b3a8e02013-03-13 05:36:4410548 tex_params));
[email protected]f598f422012-12-07 08:30:0310549 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610550}
10551
10552error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
[email protected]ed9f9cd2013-02-27 21:12:3510553 uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) {
[email protected]69023942012-11-30 19:57:1610554 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
[email protected]69023942012-11-30 19:57:1610555 GLenum target = static_cast<GLenum>(c.target);
10556 GLint level = static_cast<GLint>(c.level);
10557 GLint xoffset = static_cast<GLint>(c.xoffset);
10558 GLint yoffset = static_cast<GLint>(c.yoffset);
10559 GLsizei width = static_cast<GLsizei>(c.width);
10560 GLsizei height = static_cast<GLsizei>(c.height);
10561 GLenum format = static_cast<GLenum>(c.format);
10562 GLenum type = static_cast<GLenum>(c.type);
[email protected]32145a92012-12-17 09:01:5910563
10564 // TODO(epenner): Move this and copies of this memory validation
10565 // into ValidateTexSubImage2D step.
[email protected]69023942012-11-30 19:57:1610566 uint32 data_size;
10567 if (!GLES2Util::ComputeImageDataSizes(
10568 width, height, format, type, state_.unpack_alignment, &data_size,
10569 NULL, NULL)) {
10570 return error::kOutOfBounds;
10571 }
10572 const void* pixels = GetSharedMemoryAs<const void*>(
10573 c.data_shm_id, c.data_shm_offset, data_size);
[email protected]32145a92012-12-17 09:01:5910574
10575 // All the normal glTexSubImage2D validation.
10576 error::Error error = error::kNoError;
10577 if (!ValidateTexSubImage2D(&error, "glAsyncTexSubImage2DCHROMIUM",
10578 target, level, xoffset, yoffset, width, height, format, type, pixels)) {
10579 return error;
[email protected]69023942012-11-30 19:57:1610580 }
10581
[email protected]32145a92012-12-17 09:01:5910582 // Extra async validation.
[email protected]c986af502013-08-14 01:04:4410583 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10584 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910585 Texture* texture = texture_ref->texture();
[email protected]32145a92012-12-17 09:01:5910586 if (!ValidateAsyncTransfer(
[email protected]85a4ac22013-05-31 01:58:4710587 "glAsyncTexSubImage2DCHROMIUM", texture_ref, target, level, pixels))
[email protected]32145a92012-12-17 09:01:5910588 return error::kNoError;
10589
10590 // Guarantee async textures are always 'cleared' as follows:
10591 // - AsyncTexImage2D can not redefine an existing texture
10592 // - AsyncTexImage2D must initialize the entire image via non-null buffer.
10593 // - AsyncTexSubImage2D clears synchronously if not already cleared.
10594 // - Textures become immutable after an async call.
10595 // This way we know in all cases that an async texture is always clear.
[email protected]02965c22013-03-09 02:40:0710596 if (!texture->SafeToRenderFrom()) {
[email protected]370eaf12013-05-18 09:19:4910597 if (!texture_manager()->ClearTextureLevel(this, texture_ref,
10598 target, level)) {
[email protected]ab09b612013-03-11 22:11:5110599 LOCAL_SET_GL_ERROR(
10600 GL_OUT_OF_MEMORY,
[email protected]b04e24c2013-01-08 18:35:2510601 "glAsyncTexSubImage2DCHROMIUM", "dimensions too big");
[email protected]32145a92012-12-17 09:01:5910602 return error::kNoError;
10603 }
10604 }
10605
10606 // We know the memory/size is safe, so get the real shared memory since
10607 // it might need to be duped to prevent use-after-free of the memory.
[email protected]16ccec12013-02-28 03:40:2110608 gpu::Buffer buffer = GetSharedMemoryBuffer(c.data_shm_id);
[email protected]32145a92012-12-17 09:01:5910609 base::SharedMemory* shared_memory = buffer.shared_memory;
10610 uint32 shm_size = buffer.size;
10611 uint32 shm_data_offset = c.data_shm_offset;
10612 uint32 shm_data_size = data_size;
10613
[email protected]5b3a8e02013-03-13 05:36:4410614 // Setup the parameters.
[email protected]2a7568a2013-05-09 23:12:0310615 AsyncTexSubImage2DParams tex_params = {target, level, xoffset, yoffset,
[email protected]32145a92012-12-17 09:01:5910616 width, height, format, type};
[email protected]2a7568a2013-05-09 23:12:0310617 AsyncMemoryParams mem_params = {shared_memory, shm_size,
[email protected]32145a92012-12-17 09:01:5910618 shm_data_offset, shm_data_size};
[email protected]896425e2013-06-12 17:27:1810619 AsyncPixelTransferDelegate* delegate =
10620 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10621 if (!delegate) {
[email protected]5b3a8e02013-03-13 05:36:4410622 // TODO(epenner): We may want to enforce exclusive use
10623 // of async APIs in which case this should become an error,
10624 // (the texture should have been async defined).
[email protected]2a7568a2013-05-09 23:12:0310625 AsyncTexImage2DParams define_params = {target, level,
[email protected]5b3a8e02013-03-13 05:36:4410626 0, 0, 0, 0, 0, 0};
10627 texture->GetLevelSize(target, level, &define_params.width,
10628 &define_params.height);
10629 texture->GetLevelType(target, level, &define_params.type,
10630 &define_params.internal_format);
10631 // Set up the async state if needed, and make the texture
10632 // immutable so the async state stays valid.
[email protected]896425e2013-06-12 17:27:1810633 delegate = async_pixel_transfer_manager_->CreatePixelTransferDelegate(
[email protected]85a4ac22013-05-31 01:58:4710634 texture_ref, define_params);
[email protected]5b3a8e02013-03-13 05:36:4410635 texture->SetImmutable(true);
10636 }
10637
[email protected]896425e2013-06-12 17:27:1810638 delegate->AsyncTexSubImage2D(tex_params, mem_params);
[email protected]32145a92012-12-17 09:01:5910639 return error::kNoError;
[email protected]69023942012-11-30 19:57:1610640}
10641
[email protected]a00c1f742013-03-05 17:02:1610642error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
10643 uint32 immediate_data_size, const cmds::WaitAsyncTexImage2DCHROMIUM& c) {
10644 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
10645 GLenum target = static_cast<GLenum>(c.target);
10646
10647 if (GL_TEXTURE_2D != target) {
[email protected]ab09b612013-03-11 22:11:5110648 LOCAL_SET_GL_ERROR(
10649 GL_INVALID_ENUM, "glWaitAsyncTexImage2DCHROMIUM", "target");
[email protected]a00c1f742013-03-05 17:02:1610650 return error::kNoError;
10651 }
[email protected]c986af502013-08-14 01:04:4410652 TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget(
10653 &state_, target);
[email protected]370eaf12013-05-18 09:19:4910654 if (!texture_ref) {
[email protected]ab09b612013-03-11 22:11:5110655 LOCAL_SET_GL_ERROR(
10656 GL_INVALID_OPERATION,
10657 "glWaitAsyncTexImage2DCHROMIUM", "unknown texture");
[email protected]a00c1f742013-03-05 17:02:1610658 return error::kNoError;
10659 }
[email protected]896425e2013-06-12 17:27:1810660 AsyncPixelTransferDelegate* delegate =
10661 async_pixel_transfer_manager_->GetPixelTransferDelegate(texture_ref);
10662 if (!delegate) {
[email protected]370eaf12013-05-18 09:19:4910663 LOCAL_SET_GL_ERROR(
10664 GL_INVALID_OPERATION,
10665 "glWaitAsyncTexImage2DCHROMIUM", "No async transfer started");
10666 return error::kNoError;
10667 }
[email protected]896425e2013-06-12 17:27:1810668 delegate->WaitForTransferCompletion();
[email protected]69a8701e2013-03-07 21:31:0910669 ProcessFinishedAsyncTransfers();
[email protected]a00c1f742013-03-05 17:02:1610670 return error::kNoError;
10671}
10672
[email protected]91c94eb2013-10-22 10:32:5410673void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer(
10674 TextureRef* texture_ref) {
10675 Texture* texture = texture_ref->texture();
10676 DoDidUseTexImageIfNeeded(texture, texture->target());
10677}
10678
[email protected]96449d2c2009-11-25 00:01:3210679// Include the auto-generated part of this file. We split this because it means
10680// we can easily edit the non-auto generated parts right here in this file
10681// instead of having to edit some template or the code generator.
10682#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
10683
10684} // namespace gles2
[email protected]a7a27ace2009-12-12 00:11:2510685} // namespace gpu